r348070 - Specify constant context in constant emitter

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sat Dec 1 01:31:12 PST 2018


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 at 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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181201/57a20f02/attachment-0001.html>


More information about the cfe-commits mailing list