From 37480ab6d2b60884ab4e2272d47114a4fc5cdeb8 Mon Sep 17 00:00:00 2001 From: Ziqing Luo Date: Thu, 19 Dec 2024 15:05:45 -0800 Subject: [PATCH] [BoundsSafety] Do not check for bounds-attr output arguments in dependent contexts (#9733) The bounds-attribute-only mode may be applied to C++ programs, where attributed functions/fields may be used in dependent contexts such as a template. DO NOT type check at those places. Their instantiations will still be checked. (rdar://141708643) (cherry picked from commit d4329b6d570ab6ee206a4b57e1a4716af364e251) --- clang/lib/Sema/SemaExpr.cpp | 10 +++++++--- .../Sema/unsafe-buffer-usage-interop-crash.cpp | 7 +++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a881781fa56fe0..f95366bf952435 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -21,6 +21,7 @@ #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -8251,7 +8252,7 @@ static bool checkDynamicCountPointerAsParameter(Sema &S, FunctionDecl *FDecl, if (!ArgInfo.isCountInParamOrCountPointer() && !ArgInfo.isCountInRet() && !ParmInfo.isCountInParamOrCountPointer() && !ParmInfo.isCountInRet()) continue; - assert(!ActualArgExp->isValueDependent()); + // Disable these checks for attribute-only mode because we don't want // non-type-incompatibility errors in that mode. if (!S.getLangOpts().isBoundsSafetyAttributeOnlyMode() && @@ -8822,7 +8823,10 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, if (getLangOpts().BoundsSafetyAttributes && FDecl) { // FIXME: We need to support function pointers and blocks that don't have // function decl. - if (!checkDynamicCountPointerAsParameter(*this, FDecl, TheCall)) + + // For C++, we don't want to check for any dependent constructs. + if (TheCall->getDependence() == ExprDependence::None && + !checkDynamicCountPointerAsParameter(*this, FDecl, TheCall)) return ExprError(); if (getLangOpts().BoundsSafety) if (!checkDynamicRangePointerAsParameter(*this, FDecl, TheCall)) @@ -26016,4 +26020,4 @@ ExprResult Sema::ActOnUnsafeTerminatedByFromIndexable( PointerToTerminatorExpr, BuiltinLoc, RParenLoc); } -/* TO_UPSTREAM(BoundsSafety) OFF*/ \ No newline at end of file +/* TO_UPSTREAM(BoundsSafety) OFF*/ diff --git a/clang/test/BoundsSafety/Sema/unsafe-buffer-usage-interop-crash.cpp b/clang/test/BoundsSafety/Sema/unsafe-buffer-usage-interop-crash.cpp index 52082efc7adf36..d1dcae5e0833de 100644 --- a/clang/test/BoundsSafety/Sema/unsafe-buffer-usage-interop-crash.cpp +++ b/clang/test/BoundsSafety/Sema/unsafe-buffer-usage-interop-crash.cpp @@ -11,12 +11,15 @@ class MyClass { namespace value_dependent_assertion_violation { // Running attribute-only mode on the C++ code below crashes // previously. - void g(unsigned); + void g(int * __counted_by(n) * p, size_t n); template struct S { void f(T p) { - g(sizeof(p)); + g(nullptr, sizeof(p)); } }; + + // expected-error@-4{{incompatible dynamic count pointer argument to parameter of type 'int * __counted_by(n)*' (aka 'int **')}} + template struct S; // expected-note{{in instantiation of member function 'value_dependent_assertion_violation::S::f' requested here}} }