summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-09-20 03:29:19 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-09-20 03:29:19 +0000
commit7dbdcfcb827c68b0c380de289a2d7526666b8771 (patch)
tree3d3ff0c2f9984ac481448f9cd02e8c0a76575399
parent6cef91733c7878da84548f8175a60a3b9dfb28cc (diff)
downloadclang-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.cpp27
-rw-r--r--test/Index/Core/index-source.cpp4
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#