This seems is wrong way to handle this, and seems likely to be unsound in C++. We should be creating a ConstantExpr node wrapped around the initializer instead.
On Sat, 1 Dec 2018, 00:32 Bill Wendling via cfe-commits < cfe-commits@lists.llvm.org wrote: > Author: void > Date: Sat Dec 1 00:29:36 2018 > New Revision: 348070 > > URL: http://llvm.org/viewvc/llvm-project?rev=348070&view=rev > Log: > Specify constant context in constant emitter > > The constant emitter may need to evaluate the expression in a constant > context. > For exasmple, global initializer lists. > > Added: > cfe/trunk/test/CodeGen/builtin-constant-p.c > Modified: > cfe/trunk/lib/AST/ExprConstant.cpp > cfe/trunk/lib/CodeGen/CGExprConstant.cpp > cfe/trunk/lib/CodeGen/ConstantEmitter.h > cfe/trunk/test/Analysis/builtin-functions.cpp > > Modified: cfe/trunk/lib/AST/ExprConstant.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=348070&r1=348069&r2=348070&view=diff > > ============================================================================== > --- cfe/trunk/lib/AST/ExprConstant.cpp (original) > +++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Dec 1 00:29:36 2018 > @@ -8199,6 +8199,7 @@ bool IntExprEvaluator::VisitBuiltinCallE > // We can delay calculation of __builtin_constant_p until after > // inlining. Note: This diagnostic won't be shown to the user. > Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); > + return false; > } > return Success(false, E); > } > > Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=348070&r1=348069&r2=348070&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Sat Dec 1 00:29:36 2018 > @@ -1455,6 +1455,7 @@ llvm::Constant *ConstantEmitter::tryEmit > if (CD->isTrivial() && CD->isDefaultConstructor()) > return CGM.EmitNullConstant(D.getType()); > } > + InConstantContext = true; > } > > QualType destType = D.getType(); > @@ -1552,7 +1553,7 @@ llvm::Constant *ConstantEmitter::tryEmit > if (destType->isReferenceType()) > Success = E->EvaluateAsLValue(Result, CGM.getContext()); > else > - Success = E->EvaluateAsRValue(Result, CGM.getContext()); > + Success = E->EvaluateAsRValue(Result, CGM.getContext(), > InConstantContext); > > llvm::Constant *C; > if (Success && !Result.HasSideEffects) > > Modified: cfe/trunk/lib/CodeGen/ConstantEmitter.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ConstantEmitter.h?rev=348070&r1=348069&r2=348070&view=diff > > ============================================================================== > --- cfe/trunk/lib/CodeGen/ConstantEmitter.h (original) > +++ cfe/trunk/lib/CodeGen/ConstantEmitter.h Sat Dec 1 00:29:36 2018 > @@ -38,6 +38,9 @@ private: > /// Whether the constant-emission failed. > bool Failed = false; > > + /// Whether we're in a constant context. > + bool InConstantContext = false; > + > /// The AST address space where this (non-abstract) initializer is > going. > /// Used for generating appropriate placeholders. > LangAS DestAddressSpace; > > Modified: cfe/trunk/test/Analysis/builtin-functions.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/builtin-functions.cpp?rev=348070&r1=348069&r2=348070&view=diff > > ============================================================================== > --- cfe/trunk/test/Analysis/builtin-functions.cpp (original) > +++ cfe/trunk/test/Analysis/builtin-functions.cpp Sat Dec 1 00:29:36 2018 > @@ -70,14 +70,14 @@ void test_constant_p() { > const int j = 2; > constexpr int k = 3; > clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning > {{TRUE}} > - clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning > {{TRUE}} > + clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning > {{UNKNOWN}} > clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning > {{TRUE}} > clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning > {{TRUE}} > - clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // > expected-warning {{TRUE}} > + clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // > expected-warning {{UNKNOWN}} > clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // > expected-warning {{TRUE}} > clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // > expected-warning {{TRUE}} > clang_analyzer_eval(__builtin_constant_p(" ") == 1); // > expected-warning {{TRUE}} > - clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // > expected-warning {{TRUE}} > + clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // > expected-warning {{UNKNOWN}} > clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // > expected-warning {{FALSE}} > clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // > expected-warning {{TRUE}} > } > > Added: cfe/trunk/test/CodeGen/builtin-constant-p.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtin-constant-p.c?rev=348070&view=auto > > ============================================================================== > --- cfe/trunk/test/CodeGen/builtin-constant-p.c (added) > +++ cfe/trunk/test/CodeGen/builtin-constant-p.c Sat Dec 1 00:29:36 2018 > @@ -0,0 +1,168 @@ > +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O2 > | FileCheck %s > + > +int a = 42; > + > +inline int bcp(int x) { > + return __builtin_constant_p(x); > +} > + > +/* --- Compound literals */ > + > +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) > + struct foo f = (struct foo){ __builtin_constant_p(expr), 42 }; > + return f; > +} > + > +/* --- Pointer types */ > + > +inline int test1_i(int *x) { > + return *x; > +} > + > +int test1() { > + // CHECK: define i32 @test1 > + // CHECK: add nsw i32 %0, -13 > + // CHECK-NEXT: call i1 @llvm.is.constant.i32(i32 %sub) > + return bcp(test1_i(&a) - 13); > +} > + > +int test2() { > + // CHECK: define i32 @test2 > + // CHECK: ret i32 0 > + return __builtin_constant_p(&a - 13); > +} > + > +inline int test3_i(int *x) { > + return 42; > +} > + > +int test3() { > + // CHECK: define i32 @test3 > + // CHECK: ret i32 1 > + return bcp(test3_i(&a) - 13); > +} > + > +/* --- Aggregate types */ > + > +int b[] = {1, 2, 3}; > + > +int test4() { > + // CHECK: define i32 @test4 > + // CHECK: ret i32 0 > + return __builtin_constant_p(b); > +} > + > +const char test5_c[] = {1, 2, 3, 0}; > + > +int test5() { > + // CHECK: define i32 @test5 > + // CHECK: ret i32 0 > + return __builtin_constant_p(test5_c); > +} > + > +inline char test6_i(const char *x) { > + return x[1]; > +} > + > +int test6() { > + // CHECK: define i32 @test6 > + // CHECK: ret i32 0 > + return __builtin_constant_p(test6_i(test5_c)); > +} > + > +/* --- Non-constant global variables */ > + > +int test7() { > + // CHECK: define i32 @test7 > + // CHECK: call i1 @llvm.is.constant.i32(i32 %0) > + return bcp(a); > +} > + > +/* --- Constant global variables */ > + > +const int c = 42; > + > +int test8() { > + // CHECK: define i32 @test8 > + // CHECK: ret i32 1 > + return bcp(c); > +} > + > +/* --- Array types */ > + > +int arr[] = { 1, 2, 3 }; > +const int c_arr[] = { 1, 2, 3 }; > + > +int test9() { > + // CHECK: define i32 @test9 > + // CHECK: call i1 @llvm.is.constant.i32(i32 %0) > + return __builtin_constant_p(arr[2]); > +} > + > +int test10() { > + // CHECK: define i32 @test10 > + // CHECK: ret i32 1 > + return __builtin_constant_p(c_arr[2]); > +} > + > +int test11() { > + // CHECK: define i32 @test11 > + // CHECK: ret i32 0 > + return __builtin_constant_p(c_arr); > +} > + > +/* --- Function pointers */ > + > +int test12() { > + // CHECK: define i32 @test12 > + // CHECK: ret i32 0 > + return __builtin_constant_p(&test10); > +} > + > +int test13() { > + // CHECK: define i32 @test13 > + // CHECK: ret i32 1 > + return __builtin_constant_p(&test10 != 0); > +} > + > +typedef unsigned long uintptr_t; > +#define assign(p, v) ({ \ > + uintptr_t _r_a_p__v = (uintptr_t)(v); \ > + if (__builtin_constant_p(v) && _r_a_p__v == (uintptr_t)0) { \ > + union { \ > + uintptr_t __val; \ > + char __c[1]; \ > + } __u = { \ > + .__val = (uintptr_t)_r_a_p__v \ > + }; \ > + *(volatile unsigned int*)&p = *(unsigned int*)(__u.__c); \ > + __u.__val; \ > + } \ > + _r_a_p__v; \ > +}) > + > +typedef void fn_p(void); > +extern fn_p *dest_p; > + > +static void src_fn(void) { > +} > + > +void test14() { > + assign(dest_p, src_fn); > +} > + > +extern int test15_v; > + > +struct { const char *t; int a; } test15[] = { > + { "tag", __builtin_constant_p(test15_v) && !test15_v ? 1 : 0 } > +}; > + > +extern char test16_v; > +struct { int a; } test16 = { __builtin_constant_p(test16_v) }; > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits