]> granicus.if.org Git - clang/commitdiff
AST: Address of dllimport functions isn't constant
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 24 Jun 2014 06:40:51 +0000 (06:40 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 24 Jun 2014 06:40:51 +0000 (06:40 +0000)
The address of dllimport functions can be accessed one of two ways:
- Through the IAT which is symbolically referred to with a symbol
  starting with __imp_.
- Via the wrapper-function which ends up calling through the __imp_
  symbol.

The problem with using the wrapper-function is that it's address will
not compare as equal in all translation units.  Specifically, it will
compare unequally with the translation unit which defines the function.

This fixes PR19955.

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

lib/AST/ExprConstant.cpp
test/CodeGenCXX/PR19955.cpp
test/SemaCXX/PR19955.cpp

index d25ecd043d1bef0a596d06888409bd952927b395..c57a802512be8ed21e9d0d969905149d09517d45 100644 (file)
@@ -4373,8 +4373,11 @@ static bool EvaluateLValue(const Expr *E, LValue &Result, EvalInfo &Info) {
 }
 
 bool LValueExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl()))
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
+    if (FD->hasAttr<DLLImportAttr>())
+      return ZeroInitialization(E);
     return Success(FD);
+  }
   if (const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl()))
     return VisitVarDecl(E, VD);
   return Error(E);
index 7d54ac3899d3d403d6e2f8fea5fbb948c016a24c..9e101550b419a77a06c3b4a0444ac2e3e218766f 100644 (file)
@@ -1,10 +1,27 @@
 // RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s --check-prefix X64
 
-extern int __declspec(dllimport) x;
-extern long long y;
-// CHECK-DAG: @"\01?y@@3_JA" = global i64 0
-long long y = (long long)&x;
+extern int __declspec(dllimport) var;
+extern void __declspec(dllimport) fun();
 
-// CHECK-LABEL: @"\01??__Ey@@YAXXZ"
-// CHECK-DAG: @"\01?y@@3_JA"
+extern int *varp;
+int *varp = &var;
+// CHECK-DAG: @"\01?varp@@3PAHA" = global i32* null
+// X64-DAG: @"\01?varp@@3PEAHEA" = global i32* null
+
+extern void (*funp)();
+void (*funp)() = &fun;
+// CHECK-DAG: @"\01?funp@@3P6AXXZA" = global void ()* null
+// X64-DAG: @"\01?funp@@3P6AXXZEA" = global void ()* null
+
+// CHECK-LABEL: @"\01??__Evarp@@YAXXZ"
+// CHECK-DAG: store i32* @"\01?var@@3HA", i32** @"\01?varp@@3PAHA"
+
+// X64-LABEL: @"\01??__Evarp@@YAXXZ"
+// X64-DAG: store i32* @"\01?var@@3HA", i32** @"\01?varp@@3PEAHEA"
+
+// CHECK-LABEL: @"\01??__Efunp@@YAXXZ"()
+// CHECK-DAG: store void ()* @"\01?fun@@YAXXZ", void ()** @"\01?funp@@3P6AXXZA"
+
+// X64-LABEL: @"\01??__Efunp@@YAXXZ"()
+// X64-DAG: store void ()* @"\01?fun@@YAXXZ", void ()** @"\01?funp@@3P6AXXZEA"
index 81fa70d7f53bf03db0d3cd5f0c46ccd3cf9b9cfd..e0d4618f2c4e732f53363c5de0dbaca46511b3b8 100644 (file)
@@ -1,4 +1,7 @@
 // RUN: %clang_cc1 -triple i686-win32 -verify -std=c++11 %s
 
-extern int __attribute__((dllimport)) y;
-constexpr int *x = &y; // expected-error {{must be initialized by a constant expression}}
+extern int __attribute__((dllimport)) var;
+constexpr int *varp = &var; // expected-error {{must be initialized by a constant expression}}
+
+extern __attribute__((dllimport)) void fun();
+constexpr void (*funp)(void) = &fun; // expected-error {{must be initialized by a constant expression}}