c: assignment/init of a function pointer whose function(s)

return to one which does not return (has noreturn attribute) 
should warn as it is an unsafe assignment. // rdar://10095762
c++ already handles this. This is the c version.

llvm-svn: 141141
This commit is contained in:
Fariborz Jahanian 2011-10-05 00:05:34 +00:00
parent 202803e39c
commit 48c69106e4
3 changed files with 24 additions and 5 deletions

View File

@ -5543,13 +5543,13 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult())
return QualType();
// It's noreturn if either type is.
// functypes which return are preferred over those that do not.
if (lbaseInfo.getNoReturn() && !rbaseInfo.getNoReturn())
allLTypes = false;
else if (!lbaseInfo.getNoReturn() && rbaseInfo.getNoReturn())
allRTypes = false;
// FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
if (NoReturn != lbaseInfo.getNoReturn())
allLTypes = false;
if (NoReturn != rbaseInfo.getNoReturn())
allRTypes = false;
FunctionType::ExtInfo einfo = lbaseInfo.withNoReturn(NoReturn);

View File

@ -5277,6 +5277,9 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) {
// General pointer incompatibility takes priority over qualifiers.
return Sema::IncompatiblePointer;
}
if (!S.getLangOptions().CPlusPlus &&
S.IsNoReturnConversion(ltrans, rtrans, ltrans))
return Sema::IncompatiblePointer;
return ConvTy;
}

View File

@ -0,0 +1,16 @@
// RUN: %clang_cc1 %s -fsyntax-only -verify
// rdar://10095762
typedef void (*Fn_noret)(void) __attribute__((noreturn));
typedef void (*Fn_ret)(void);
void foo(void);
void foo_noret(void) __attribute__((noreturn));
void test() {
Fn_noret fn2 = &foo; // expected-warning {{incompatible pointer types initializing 'Fn_noret'}}
Fn_noret fn3 = &foo_noret;
Fn_ret fn4 = &foo_noret;
Fn_ret fn5 = &foo;
}