[cfe-commits] r170827 - in /cfe/trunk: lib/CodeGen/CGDecl.cpp lib/CodeGen/CGExpr.cpp lib/Sema/SemaDecl.cpp test/CodeGen/linkage-redecl.c

Rafael Espindola rafael.espindola at gmail.com
Thu Dec 20 17:21:33 PST 2012


Author: rafael
Date: Thu Dec 20 19:21:33 2012
New Revision: 170827

URL: http://llvm.org/viewvc/llvm-project?rev=170827&view=rev
Log:
Don't eagerly emit a global static merged with a local extern.

When we are visiting the extern declaration of 'i' in

static int i = 99;
int foo() {
  extern int i;
  return i;
}

We should not try to handle it as if it was an function static. That is, we
must consider the written storage class.

Fixing this then exposes that the assert in EmitGlobalVarDeclLValue and the
if leading to its call are not completely accurate. They were passing before
because the second decl was marked as having external storage. I changed them
to check the linkage, which I find easier to understand.

Last but not least, there is something strange going on with cuda and opencl.
My guess is that the linkage computation for these languages needs to be
audited, but I didn't want to change that in this patch so I just updated
the storage classes to keep the current behavior.

Thanks to Reed Kotler for reporting this.

Modified:
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/CodeGen/linkage-redecl.c

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=170827&r1=170826&r2=170827&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Dec 20 19:21:33 2012
@@ -107,7 +107,7 @@
 /// EmitVarDecl - This method handles emission of any variable declaration
 /// inside a function, including static vars etc.
 void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
-  switch (D.getStorageClass()) {
+  switch (D.getStorageClassAsWritten()) {
   case SC_None:
   case SC_Auto:
   case SC_Register:

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=170827&r1=170826&r2=170827&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Dec 20 19:21:33 2012
@@ -1583,8 +1583,7 @@
 
 static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
                                       const Expr *E, const VarDecl *VD) {
-  assert((VD->hasExternalStorage() || VD->isFileVarDecl()) &&
-         "Var decl must have external storage or be a file var decl!");
+  assert(VD->hasLinkage() && "Var decl must have linkage!");
 
   llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD);
   llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType());
@@ -1658,7 +1657,7 @@
 
   if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
     // Check if this is a global variable.
-    if (VD->hasExternalStorage() || VD->isFileVarDecl()) 
+    if (VD->hasLinkage())
       return EmitGlobalVarDeclLValue(*this, E, VD);
 
     bool isBlockVariable = VD->hasAttr<BlocksAttr>();

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=170827&r1=170826&r2=170827&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Dec 20 19:21:33 2012
@@ -4284,8 +4284,10 @@
   if (getLangOpts().OpenCL) {
     // Set up the special work-group-local storage class for variables in the
     // OpenCL __local address space.
-    if (R.getAddressSpace() == LangAS::opencl_local)
+    if (R.getAddressSpace() == LangAS::opencl_local) {
       SC = SC_OpenCLWorkGroupLocal;
+      SCAsWritten = SC_OpenCLWorkGroupLocal;
+    }
   }
 
   bool isExplicitSpecialization = false;
@@ -4420,8 +4422,11 @@
     // CUDA B.2.5: "__shared__ and __constant__ variables have implied static
     // storage [duration]."
     if (SC == SC_None && S->getFnParent() != 0 &&
-       (NewVD->hasAttr<CUDASharedAttr>() || NewVD->hasAttr<CUDAConstantAttr>()))
+        (NewVD->hasAttr<CUDASharedAttr>() ||
+         NewVD->hasAttr<CUDAConstantAttr>())) {
       NewVD->setStorageClass(SC_Static);
+      NewVD->setStorageClassAsWritten(SC_Static);
+    }
   }
 
   // In auto-retain/release, infer strong retension for variables of

Modified: cfe/trunk/test/CodeGen/linkage-redecl.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/linkage-redecl.c?rev=170827&r1=170826&r2=170827&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/linkage-redecl.c (original)
+++ cfe/trunk/test/CodeGen/linkage-redecl.c Thu Dec 20 19:21:33 2012
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - |grep internal
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: @test2_i = internal global i32 99
+static int test2_i = 99;
+int test2_f() {
+  extern int test2_i;
+  return test2_i;
+}
 
 // C99 6.2.2p3
 // PR3425
@@ -9,3 +16,4 @@
 }
 
 extern void f(int x) { } // still has internal linkage
+// CHECK: define internal void @f





More information about the cfe-commits mailing list