]> granicus.if.org Git - clang/commitdiff
When calling the cleanup function specified by __attribute__((cleanup)), make sure...
authorAnders Carlsson <andersca@mac.com>
Sun, 26 Apr 2009 00:34:20 +0000 (00:34 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 26 Apr 2009 00:34:20 +0000 (00:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70098 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDecl.cpp
test/CodeGen/attr-cleanup.c [new file with mode: 0644]

index 0a1d1d0bd1eb55f2a1e0fe704a1d536d249df874..15f1e1d431856938c38e5ebea6aaa181dd8d71ec 100644 (file)
@@ -405,11 +405,22 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
   
     CleanupScope scope(*this);
 
+    const CGFunctionInfo &Info = CGM.getTypes().getFunctionInfo(FD);
+
+    // In some cases, the type of the function argument will be different from
+    // the type of the pointer. An example of this is
+    // void f(void* arg);
+    // __attribute__((cleanup(f))) void *g;
+    // 
+    // To fix this we insert a bitcast here.
+    QualType ArgTy = Info.arg_begin()->type;
+    DeclPtr = Builder.CreateBitCast(DeclPtr, ConvertType(ArgTy));
+    
     CallArgList Args;
     Args.push_back(std::make_pair(RValue::get(DeclPtr), 
                                   getContext().getPointerType(D.getType())));
-      
-    EmitCall(CGM.getTypes().getFunctionInfo(FD), F, Args);
+    
+    EmitCall(Info, F, Args);
   }
 
   if (needsDispose && CGM.getLangOptions().getGCMode() != LangOptions::GCOnly) {
diff --git a/test/CodeGen/attr-cleanup.c b/test/CodeGen/attr-cleanup.c
new file mode 100644 (file)
index 0000000..03dde33
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang-cc -emit-llvm %s -o %t
+
+// <rdar://problem/6827047>
+void f(void* arg);
+void g() {
+       __attribute__((cleanup(f))) void *g;
+}
+