From 24f2801e2c0ac5c1fc8549ed8f91b4d0fbd8c6ac Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 27 Apr 2010 21:07:06 +0000 Subject: [PATCH] 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 --- lib/AST/ASTContext.cpp | 21 ++++++++------------- test/Sema/attr-regparm.c | 14 +++++++++----- 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'}} -- 2.50.0