]> granicus.if.org Git - clang/commitdiff
PR3835: Interaction with ABI structure passing can inhibit
authorDaniel Dunbar <daniel@zuster.org>
Wed, 18 Mar 2009 19:51:01 +0000 (19:51 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 18 Mar 2009 19:51:01 +0000 (19:51 +0000)
readnone/readonly attributes.

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

lib/CodeGen/CGCall.cpp
test/CodeGen/struct-passing.c [new file with mode: 0644]

index 9e52cbb79cf81ca9146a0271c85012cc1b52c3f3..fd33b50e79e6f561e1066e2a9a2cc04e2af49366 100644 (file)
@@ -1467,6 +1467,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
                                                 llvm::Attribute::StructRet |
                                                 llvm::Attribute::NoAlias));
     ++Index;
+    // sret disables readnone and readonly
+    FuncAttrs &= ~(llvm::Attribute::ReadOnly |
+                   llvm::Attribute::ReadNone);
     break;
 
   case ABIArgInfo::Ignore:
@@ -1493,6 +1496,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
       Attributes |= llvm::Attribute::ByVal;
       Attributes |= 
         llvm::Attribute::constructAlignmentFromInt(AI.getIndirectAlign());
+      // byval disables readnone and readonly.
+      FuncAttrs &= ~(llvm::Attribute::ReadOnly |
+                     llvm::Attribute::ReadNone);
       break;
       
     case ABIArgInfo::Direct:
diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c
new file mode 100644 (file)
index 0000000..305101d
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: clang -triple i386-pc-linux-gnu -emit-llvm -o %t %s &&
+// RUN: grep 'declare i32 @f0() readnone$' %t &&
+// RUN: grep 'declare i32 @f1() readonly$' %t &&
+// RUN: grep 'declare void @f2(.* noalias sret)$' %t &&
+// RUN: grep 'declare void @f3(.* noalias sret)$' %t &&
+// RUN: grep 'declare void @f4(.* byval)$' %t &&
+// RUN: grep 'declare void @f5(.* byval)$' %t &&
+// RUN: true
+// PR3835
+
+typedef int T0;
+typedef struct { int a[16]; } T1;
+
+T0 __attribute__((const)) f0(void);
+T0 __attribute__((pure)) f1(void);
+T1 __attribute__((const)) f2(void);
+T1 __attribute__((pure)) f3(void);
+void __attribute__((const)) f4(T1 a);
+void __attribute__((pure)) f5(T1 a);
+
+void *ps[] = { f0, f1, f2, f3, f4, f5 };