efriedma created this revision.
efriedma added reviewers: rjmccall, rsmith.
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, so I'm not sure it's worth fixing.  We would either need to store more 
information in the AST, or somehow make constant evaluation keep track of the 
parent function of the PredefinedExpr.

This could change behavior in some situations involving BlockDecl. Currently, 
CodeGenFunction::EmitPredefinedLValue has some logic to intentionally emit a 
string different from what Sema computed.  Specifically, it does two things: 
one, it appends numbers to the string if there are multiple block expressions 
in the function that use __func__, and two, it rewrites __func__ for blocks in 
the initializer for a global variable. This code skips that logic... but 
changing the string in CodeGen is fundamentally broken 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 .


Repository:
  rC Clang

https://reviews.llvm.org/D56821

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


Index: test/CodeGenCXX/predefined-expr-cxx14.cpp
===================================================================
--- test/CodeGenCXX/predefined-expr-cxx14.cpp
+++ test/CodeGenCXX/predefined-expr-cxx14.cpp
@@ -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 @@
   const char *getFunc() const { return Func; }
 };
 
+constexpr const char* ConstexprPrettyFn() {
+  return __PRETTY_FUNCTION__;
+}
+const char* ConstexprPrettyVar = ConstexprPrettyFn();
+
 int
 main() {
   int a;
Index: test/CodeGen/const-init.c
===================================================================
--- test/CodeGen/const-init.c
+++ test/CodeGen/const-init.c
@@ -121,8 +121,8 @@
 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 @@
       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: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -1789,17 +1789,7 @@
 
 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: test/CodeGenCXX/predefined-expr-cxx14.cpp
===================================================================
--- test/CodeGenCXX/predefined-expr-cxx14.cpp
+++ test/CodeGenCXX/predefined-expr-cxx14.cpp
@@ -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 @@
   const char *getFunc() const { return Func; }
 };
 
+constexpr const char* ConstexprPrettyFn() {
+  return __PRETTY_FUNCTION__;
+}
+const char* ConstexprPrettyVar = ConstexprPrettyFn();
+
 int
 main() {
   int a;
Index: test/CodeGen/const-init.c
===================================================================
--- test/CodeGen/const-init.c
+++ test/CodeGen/const-init.c
@@ -121,8 +121,8 @@
 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 @@
       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: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -1789,17 +1789,7 @@
 
 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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to