From: Eric Christopher Date: Mon, 15 Aug 2011 22:38:22 +0000 (+0000) Subject: 'pure' and 'const' functions should also be marked nounwind. Migrate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=041087caec03e8855770695d3eabc0feb031f6ed;p=clang 'pure' and 'const' functions should also be marked nounwind. Migrate test over from llvm/test/FrontendC++ and update others to account for the change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137669 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 023dd2267c..dc3e702d6a 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -739,10 +739,15 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, if (TargetDecl->hasAttr()) FuncAttrs |= llvm::Attribute::NoReturn; - if (TargetDecl->hasAttr()) + + // 'const' and 'pure' attribute functions are also nounwind. + if (TargetDecl->hasAttr()) { FuncAttrs |= llvm::Attribute::ReadNone; - else if (TargetDecl->hasAttr()) + FuncAttrs |= llvm::Attribute::NoUnwind; + } else if (TargetDecl->hasAttr()) { FuncAttrs |= llvm::Attribute::ReadOnly; + FuncAttrs |= llvm::Attribute::NoUnwind; + } if (TargetDecl->hasAttr()) RetAttrs |= llvm::Attribute::NoAlias; } diff --git a/test/CodeGen/libcalls.c b/test/CodeGen/libcalls.c index 5ff684fd5b..458c591837 100644 --- a/test/CodeGen/libcalls.c +++ b/test/CodeGen/libcalls.c @@ -24,9 +24,9 @@ void test_sqrt(float a0, double a1, long double a2) { // CHECK-YES: declare float @sqrtf(float) // CHECK-YES: declare double @sqrt(double) // CHECK-YES: declare x86_fp80 @sqrtl(x86_fp80) -// CHECK-NO: declare float @sqrtf(float) readnone -// CHECK-NO: declare double @sqrt(double) readnone -// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) readnone +// CHECK-NO: declare float @sqrtf(float) nounwind readnone +// CHECK-NO: declare double @sqrt(double) nounwind readnone +// CHECK-NO: declare x86_fp80 @sqrtl(x86_fp80) nounwind readnone // CHECK-YES: define void @test_pow // CHECK-NO: define void @test_pow diff --git a/test/CodeGen/struct-passing.c b/test/CodeGen/struct-passing.c index 8e5c0adcfc..efb00efd53 100644 --- a/test/CodeGen/struct-passing.c +++ b/test/CodeGen/struct-passing.c @@ -16,8 +16,8 @@ void __attribute__((pure)) f5(T1 a); void *ps[] = { f0, f1, f2, f3, f4, f5 }; -// CHECK: declare i32 @f0() readnone -// CHECK: declare i32 @f1() readonly +// CHECK: declare i32 @f0() nounwind readnone +// CHECK: declare i32 @f1() nounwind readonly // CHECK: declare void @f2({{.*}} sret) // CHECK: declare void @f3({{.*}} sret) // CHECK: declare void @f4({{.*}} byval align 4) diff --git a/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp new file mode 100644 index 0000000000..708920792b --- /dev/null +++ b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fexceptions -emit-llvm %s -o - | grep nounwind | count 4 +int c(void) __attribute__((const)); +int p(void) __attribute__((pure)); +int t(void); + +int f(void) { + return c() + p() + t(); +}