]> granicus.if.org Git - clang/commitdiff
[CodeGen] Always use string computed in Sema for PredefinedExpr
authorEli Friedman <efriedma@codeaurora.org>
Tue, 22 Jan 2019 00:11:17 +0000 (00:11 +0000)
committerEli Friedman <efriedma@codeaurora.org>
Tue, 22 Jan 2019 00:11:17 +0000 (00:11 +0000)
We can't use any other string, anyway, because its type wouldn't
match the type of the PredefinedExpr.

With this change, we don't compute a "nice" name for the __func__ global
when it's used in the initializer for a constant. This doesn't seem like
a great loss, and I'm not sure how to fix it without either storing more
information in the AST, or somehow threading through the information
from ExprConstant.cpp.

This could break some situations involving BlockDecl; currently,
CodeGenFunction::EmitPredefinedLValue has some logic to intentionally
emit a string different from what Sema computed.  This code skips that
logic... but that logic can't work correctly in general anyway.  (For
example, sizeof(__func__) returns the wrong result.) Hopefully this
doesn't affect practical code.

Fixes https://bugs.llvm.org/show_bug.cgi?id=40313 .

Differential Revision: https://reviews.llvm.org/D56821

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@351766 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprConstant.cpp
test/CodeGen/const-init.c
test/CodeGenCXX/predefined-expr-cxx14.cpp

index 09a035679b2a286210ea57a361b3ebb57923eea4..48ab2522e83f2e55183c95e6da29ea9b4e005579 100644 (file)
@@ -1788,17 +1788,7 @@ ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *E) {
 
 ConstantLValue
 ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *E) {
-  if (auto CGF = Emitter.CGF) {
-    LValue Res = CGF->EmitPredefinedLValue(E);
-    return cast<ConstantAddress>(Res.getAddress());
-  }
-
-  auto kind = E->getIdentKind();
-  if (kind == PredefinedExpr::PrettyFunction) {
-    return CGM.GetAddrOfConstantCString("top level", ".tmp");
-  }
-
-  return CGM.GetAddrOfConstantCString("", ".tmp");
+  return CGM.GetAddrOfConstantStringFromLiteral(E->getFunctionName());
 }
 
 ConstantLValue
index 3fd231b630ee7d1286770544c79c4599b674bcef..41ac8f2eb05bb9eea76c4ea477090296c0f349bd 100644 (file)
@@ -121,8 +121,8 @@ struct g22 {int x;} __attribute((packed));
 struct g23 {char a; short b; char c; struct g22 d;};
 struct g23 g24 = {1,2,3,4};
 
-// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8], [4 x i8]* @__func__.g25, i32 0, i32 0)
-// CHECK: @__func__.g25 = private unnamed_addr constant [4 x i8] c"g25\00"
+// CHECK: @g25.g26 = internal global i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[FUNC:.*]], i32 0, i32 0)
+// CHECK: @[[FUNC]] = private unnamed_addr constant [4 x i8] c"g25\00"
 int g25() {
   static const char *g26 = __func__;
   return *g26;
@@ -153,7 +153,7 @@ void g29() {
       DCC_PASSWD passwd;
   } DCC_SRVR_NM;
   // CHECK: @g29.a = internal global %struct.DCC_SRVR_NM { [2 x i8] c"@\00" }, align 1
-  // CHECK: @g29.b = internal global [1 x i32] [i32 ptrtoint ([5 x i8]* @.str to i32)], align 4
+  // CHECK: @g29.b = internal global [1 x i32] [i32 ptrtoint ([5 x i8]* @.str.1 to i32)], align 4
   // CHECK: @g29.c = internal global [1 x i32] [i32 97], align 4
   static DCC_SRVR_NM a = { {"@"} };
   static int b[1] = { "asdf" }; // expected-warning {{incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [5]'}}
index dd531e3112b6e22b60539c547d606429518e9ab5..ec7c3db7bd42b69612d2ae63e5d49d26df5a72bf 100644 (file)
@@ -20,6 +20,8 @@
 // CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [31 x i8] c"~ClassBlockConstr_block_invoke\00"
 // CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [30 x i8] c"ClassBlockConstr_block_invoke\00"
 
+// CHECK-DAG: private unnamed_addr constant [32 x i8] c"const char *ConstexprPrettyFn()\00"
+
 int printf(const char * _Format, ...);
 
 class ClassInTopLevelNamespace {
@@ -83,6 +85,11 @@ public:
   const char *getFunc() const { return Func; }
 };
 
+constexpr const char* ConstexprPrettyFn() {
+  return __PRETTY_FUNCTION__;
+}
+const char* ConstexprPrettyVar = ConstexprPrettyFn();
+
 int
 main() {
   int a;