forked from OSchip/llvm-project
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
This commit is contained in:
parent
7459398a43
commit
1af8dd6a1e
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue