Skip to content

Commit 48c6910

Browse files
author
Fariborz Jahanian
committed
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
1 parent 202803e commit 48c6910

File tree

3 files changed

+24
-5
lines changed

3 files changed

+24
-5
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5543,13 +5543,13 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
55435543
if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult())
55445544
return QualType();
55455545

5546-
// It's noreturn if either type is.
5547-
// FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
5548-
bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
5549-
if (NoReturn != lbaseInfo.getNoReturn())
5546+
// functypes which return are preferred over those that do not.
5547+
if (lbaseInfo.getNoReturn() && !rbaseInfo.getNoReturn())
55505548
allLTypes = false;
5551-
if (NoReturn != rbaseInfo.getNoReturn())
5549+
else if (!lbaseInfo.getNoReturn() && rbaseInfo.getNoReturn())
55525550
allRTypes = false;
5551+
// FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
5552+
bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
55535553

55545554
FunctionType::ExtInfo einfo = lbaseInfo.withNoReturn(NoReturn);
55555555

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5277,6 +5277,9 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) {
52775277
// General pointer incompatibility takes priority over qualifiers.
52785278
return Sema::IncompatiblePointer;
52795279
}
5280+
if (!S.getLangOptions().CPlusPlus &&
5281+
S.IsNoReturnConversion(ltrans, rtrans, ltrans))
5282+
return Sema::IncompatiblePointer;
52805283
return ConvTy;
52815284
}
52825285

clang/test/Sema/initialize-noreturn.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 %s -fsyntax-only -verify
2+
// rdar://10095762
3+
4+
typedef void (*Fn_noret)(void) __attribute__((noreturn));
5+
typedef void (*Fn_ret)(void);
6+
7+
void foo(void);
8+
void foo_noret(void) __attribute__((noreturn));
9+
10+
void test() {
11+
Fn_noret fn2 = &foo; // expected-warning {{incompatible pointer types initializing 'Fn_noret'}}
12+
Fn_noret fn3 = &foo_noret;
13+
Fn_ret fn4 = &foo_noret;
14+
Fn_ret fn5 = &foo;
15+
}
16+

0 commit comments

Comments
 (0)