diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-09-20 03:29:19 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-09-20 03:29:19 +0000 |
commit | 7dbdcfcb827c68b0c380de289a2d7526666b8771 (patch) | |
tree | 3d3ff0c2f9984ac481448f9cd02e8c0a76575399 | |
parent | 6cef91733c7878da84548f8175a60a3b9dfb28cc (diff) | |
download | clang-7dbdcfcb827c68b0c380de289a2d7526666b8771.tar.gz |
Finish building the full-expression for a static_assert expression
before evaluating it rather than afterwards.
This is groundwork for C++20's P0784R7, where non-trivial destructors
can be constexpr, so we need ExprWithCleanups markers in constant
expressions.
No significant functionality change intended (though this fixes a bug
only visible through libclang / -ast-dump / tooling: we now store the
converted condition on the StaticAssertDecl rather than the original).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372368 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 27 | ||||
-rw-r--r-- | test/Index/Core/index-source.cpp | 4 |
2 files changed, 20 insertions, 11 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f7c2695d57..9a1a9c0d67 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -14182,8 +14182,17 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, if (Converted.isInvalid()) Failed = true; + ExprResult FullAssertExpr = + ActOnFinishFullExpr(Converted.get(), StaticAssertLoc, + /*DiscardedValue*/ false, + /*IsConstexpr*/ true); + if (FullAssertExpr.isInvalid()) + Failed = true; + else + AssertExpr = FullAssertExpr.get(); + llvm::APSInt Cond; - if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond, + if (!Failed && VerifyIntegerConstantExpression(AssertExpr, &Cond, diag::err_static_assert_expression_is_not_constant, /*AllowFold=*/false).isInvalid()) Failed = true; @@ -14209,16 +14218,16 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, } Failed = true; } + } else { + ExprResult FullAssertExpr = ActOnFinishFullExpr(AssertExpr, StaticAssertLoc, + /*DiscardedValue*/false, + /*IsConstexpr*/true); + if (FullAssertExpr.isInvalid()) + Failed = true; + else + AssertExpr = FullAssertExpr.get(); } - ExprResult FullAssertExpr = ActOnFinishFullExpr(AssertExpr, StaticAssertLoc, - /*DiscardedValue*/false, - /*IsConstexpr*/true); - if (FullAssertExpr.isInvalid()) - Failed = true; - else - AssertExpr = FullAssertExpr.get(); - Decl *Decl = StaticAssertDecl::Create(Context, CurContext, StaticAssertLoc, AssertExpr, AssertMessage, RParenLoc, Failed); diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp index b57b156072..f159b1c884 100644 --- a/test/Index/Core/index-source.cpp +++ b/test/Index/Core/index-source.cpp @@ -461,12 +461,12 @@ struct StaticAssertRef { }; static_assert(StaticAssertRef::constVar, "index static asserts"); -// CHECK: [[@LINE-1]]:32 | static-property/C++ | constVar | c:@S@StaticAssertRef@constVar | __ZN15StaticAssertRef8constVarE | Ref | rel: 0 +// CHECK: [[@LINE-1]]:32 | static-property/C++ | constVar | c:@S@StaticAssertRef@constVar | __ZN15StaticAssertRef8constVarE | Ref,Read | rel: 0 // CHECK: [[@LINE-2]]:15 | struct/C++ | StaticAssertRef | c:@S@StaticAssertRef | <no-cgname> | Ref | rel: 0 void staticAssertInFn() { static_assert(StaticAssertRef::constVar, "index static asserts"); -// CHECK: [[@LINE-1]]:34 | static-property/C++ | constVar | c:@S@StaticAssertRef@constVar | __ZN15StaticAssertRef8constVarE | Ref,RelCont | rel: 1 +// CHECK: [[@LINE-1]]:34 | static-property/C++ | constVar | c:@S@StaticAssertRef@constVar | __ZN15StaticAssertRef8constVarE | Ref,Read,RelCont | rel: 1 // CHECK-NEXT: RelCont | staticAssertInFn | c:@F@staticAssertInFn# // CHECK: [[@LINE-3]]:17 | struct/C++ | StaticAssertRef | c:@S@StaticAssertRef | <no-cgname> | Ref,RelCont | rel: 1 // CHECK-NEXT: RelCont | staticAssertInFn | c:@F@staticAssertInFn# |