summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2018-11-24 10:45:55 +0000
committerBill Wendling <isanbard@gmail.com>2018-11-24 10:45:55 +0000
commit1af8dd6a1edb1d3a2e302b1e92d53d877a7892e1 (patch)
tree83ebeccd064907913a4f21e89e7a83db6e6af0ad
parent7459398a436f67f304c8653f39b8d82109778fec (diff)
downloadbcm5719-llvm-1af8dd6a1edb1d3a2e302b1e92d53d877a7892e1.tar.gz
bcm5719-llvm-1af8dd6a1edb1d3a2e302b1e92d53d877a7892e1.zip
isEvaluatable() implies a constant context.
Assume that we're in a constant context if we're asking if the expression can be compiled into a constant initializer. This fixes the issue where a __builtin_constant_p() in a compound literal was diagnosed as not being constant, even though it's always possible to convert the builtin into a constant. llvm-svn: 347512
-rw-r--r--clang/include/clang/AST/Expr.h3
-rw-r--r--clang/lib/AST/ExprConstant.cpp6
-rw-r--r--clang/lib/Sema/SemaExpr.cpp7
-rw-r--r--clang/test/CodeGen/builtin-constant-p.c3
-rw-r--r--clang/test/SemaCXX/compound-literal.cpp3
5 files changed, 17 insertions, 5 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 9b769079d39..7df7b56ca1f 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -583,7 +583,8 @@ public:
/// this function returns true, it returns the folded constant in Result. If
/// the expression is a glvalue, an lvalue-to-rvalue conversion will be
/// applied.
- bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const;
+ bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
+ bool InConstantContext = false) const;
/// EvaluateAsBooleanCondition - Return true if this is a constant
/// which we can fold and convert to a boolean condition using
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 4ad25b96856..29508368d75 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10807,8 +10807,10 @@ static bool EvaluateAsInt(const Expr *E, Expr::EvalResult &ExprResult,
/// we want to. If this function returns true, it returns the folded constant
/// in Result. If this expression is a glvalue, an lvalue-to-rvalue conversion
/// will be applied to the result.
-bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
+bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx,
+ bool InConstantContext) const {
EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
+ Info.InConstantContext = InConstantContext;
return ::EvaluateAsRValue(this, Result, Ctx, Info);
}
@@ -10909,7 +10911,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
/// constant folded, but discard the result.
bool Expr::isEvaluatable(const ASTContext &Ctx, SideEffectsKind SEK) const {
EvalResult Result;
- return EvaluateAsRValue(Result, Ctx) &&
+ return EvaluateAsRValue(Result, Ctx, /* in constant context */ true) &&
!hasUnacceptableSideEffect(Result, SEK);
}
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5d99a7ed69a..925988e4a7f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5798,7 +5798,12 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
: VK_LValue;
if (isFileScope)
- LiteralExpr = ConstantExpr::Create(Context, LiteralExpr);
+ if (auto ILE = dyn_cast<InitListExpr>(LiteralExpr))
+ for (unsigned i = 0, j = ILE->getNumInits(); i != j; i++) {
+ Expr *Init = ILE->getInit(i);
+ ILE->setInit(i, ConstantExpr::Create(Context, Init));
+ }
+
Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
VK, LiteralExpr, isFileScope);
if (isFileScope) {
diff --git a/clang/test/CodeGen/builtin-constant-p.c b/clang/test/CodeGen/builtin-constant-p.c
index 3f1225fb8b2..5cdcc721235 100644
--- a/clang/test/CodeGen/builtin-constant-p.c
+++ b/clang/test/CodeGen/builtin-constant-p.c
@@ -10,6 +10,9 @@ inline int bcp(int x) {
struct foo { int x, y; };
+int y;
+struct foo f = (struct foo){ __builtin_constant_p(y), 42 };
+
struct foo test0(int expr) {
// CHECK: define i64 @test0(i32 %expr)
// CHECK: call i1 @llvm.is.constant.i32(i32 %expr)
diff --git a/clang/test/SemaCXX/compound-literal.cpp b/clang/test/SemaCXX/compound-literal.cpp
index 5ada9e72f97..353be2cf48e 100644
--- a/clang/test/SemaCXX/compound-literal.cpp
+++ b/clang/test/SemaCXX/compound-literal.cpp
@@ -37,9 +37,10 @@ namespace brace_initializers {
POD p = (POD){1, 2};
// CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'
// CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD'
- // CHECK-NEXT: ConstantExpr {{.*}} 'brace_initializers::POD'
// CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD'
+ // CHECK-NEXT: ConstantExpr {{.*}}
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
+ // CHECK-NEXT: ConstantExpr {{.*}}
// CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
void test() {
OpenPOWER on IntegriCloud