aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2010-04-27 21:07:06 +0000
committerEli Friedman <eli.friedman@gmail.com>2010-04-27 21:07:06 +0000
commit24f2801e2c0ac5c1fc8549ed8f91b4d0fbd8c6ac (patch)
tree470b0db5f9f2b31f1467a60a73c85f0ad9ae2870
parent1c63b9c15d48cb8c833a4b2d6fd6c496c0766e88 (diff)
Fix for PR6953: per gcc, regparm and noreturn affect the compatibility of
function types. This could potentially have unexpected side-effects, so look here if there are new regressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102464 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ASTContext.cpp21
-rw-r--r--test/Sema/attr-regparm.c14
2 files changed, 17 insertions, 18 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4d7ea40079..868054fe0e 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4311,21 +4311,16 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
allLTypes = false;
if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType()))
allRTypes = false;
- // FIXME: double check this
- // FIXME: should we error if lbase->getRegParmAttr() != 0 &&
- // rbase->getRegParmAttr() != 0 &&
- // lbase->getRegParmAttr() != rbase->getRegParmAttr()?
+
+ // Check misc function attributes
FunctionType::ExtInfo lbaseInfo = lbase->getExtInfo();
FunctionType::ExtInfo rbaseInfo = rbase->getExtInfo();
- unsigned RegParm = lbaseInfo.getRegParm() == 0 ? rbaseInfo.getRegParm() :
- lbaseInfo.getRegParm();
- bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
- if (NoReturn != lbaseInfo.getNoReturn() ||
- RegParm != lbaseInfo.getRegParm())
- allLTypes = false;
- if (NoReturn != rbaseInfo.getNoReturn() ||
- RegParm != rbaseInfo.getRegParm())
- allRTypes = false;
+ // Per gcc, compatible functions must have compatible regparm and noreturn
+ // attributes.
+ unsigned RegParm = lbaseInfo.getRegParm();
+ bool NoReturn = lbaseInfo.getNoReturn();
+ if (NoReturn != rbaseInfo.getNoReturn() || RegParm != rbaseInfo.getRegParm())
+ return QualType();
CallingConv lcc = lbaseInfo.getCC();
CallingConv rcc = rbaseInfo.getCC();
// Compatible functions must have compatible calling conventions
diff --git a/test/Sema/attr-regparm.c b/test/Sema/attr-regparm.c
index 045a41396e..5764097875 100644
--- a/test/Sema/attr-regparm.c
+++ b/test/Sema/attr-regparm.c
@@ -1,7 +1,11 @@
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
-__attribute((regparm(2))) int x(void);
-__attribute((regparm(1.0))) int x(void); // expected-error{{'regparm' attribute requires integer constant}}
-__attribute((regparm(-1))) int x(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
-__attribute((regparm(5))) int x(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
-__attribute((regparm(5,3))) int x(void); // expected-error{{attribute requires 1 argument(s)}}
+__attribute((regparm(2))) int a(void);
+__attribute((regparm(1.0))) int b(void); // expected-error{{'regparm' attribute requires integer constant}}
+__attribute((regparm(-1))) int c(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
+__attribute((regparm(5))) int d(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
+__attribute((regparm(5,3))) int e(void); // expected-error{{attribute requires 1 argument(s)}}
+int f(void);
+__attribute((regparm(0))) int f(void);
+__attribute((regparm(1))) int g(void); // expected-note{{previous declaration is here}}
+__attribute((regparm(2))) int g(void); // expected-error{{conflicting types for 'g'}}