From d4dd30ff212acdc11c79b026c97cc72d7d89f565 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Thu, 18 Oct 2007 05:13:08 +0000 Subject: [PATCH] Fix a bug in Sema::CheckConditionalOperands(). When mixing pointers and null pointer constants, we need to promote the null pointer constant (which is an integer) to the pointer type. Test case is self explanatory. This surfaced yesterday, when compiling test/Sema/cocoa.m on Leopard. Since this has nothing to do with ObjC, it's kind of bizarre this hasn't shown up before. I imagine Cocoa.h on Leopard may have changed recently? Thanks to Ted for localizing the bug and giving me a useful AST dump... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43114 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/SemaExpr.cpp | 29 ++++++++++++++++------------- test/Sema/implicit-cast.c | 8 ++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 test/Sema/implicit-cast.c diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index f3381b8148..12897ea291 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -705,6 +705,16 @@ ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, return new CastExpr(castType, castExpr, LParenLoc); } +// promoteExprToType - a helper function to ensure we create exactly one +// ImplicitCastExpr. +static void promoteExprToType(Expr *&expr, QualType type) { + if (ImplicitCastExpr *impCast = dyn_cast(expr)) + impCast->setType(type); + else + expr = new ImplicitCastExpr(type, expr); + return; +} + inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) { UsualUnaryConversions(cond); @@ -738,11 +748,14 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 } } // C99 6.5.15p3 - if (lexT->isPointerType() && rex->isNullPointerConstant(Context)) + if (lexT->isPointerType() && rex->isNullPointerConstant(Context)) { + promoteExprToType(rex, lexT); // promote the null to a pointer. return lexT; - if (rexT->isPointerType() && lex->isNullPointerConstant(Context)) + } + if (rexT->isPointerType() && lex->isNullPointerConstant(Context)) { + promoteExprToType(lex, rexT); // promote the null to a pointer. return rexT; - + } if (const PointerType *LHSPT = lexT->getAsPointerType()) { // C99 6.5.15p3,6 if (const PointerType *RHSPT = rexT->getAsPointerType()) { // get the "pointed to" types @@ -797,16 +810,6 @@ Action::ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, return new ConditionalOperator(CondExpr, LHSExpr, RHSExpr, result); } -// promoteExprToType - a helper function to ensure we create exactly one -// ImplicitCastExpr. As a convenience (to the caller), we return the type. -static void promoteExprToType(Expr *&expr, QualType type) { - if (ImplicitCastExpr *impCast = dyn_cast(expr)) - impCast->setType(type); - else - expr = new ImplicitCastExpr(type, expr); - return; -} - /// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that /// do not have a prototype. Integer promotions are performed on each /// argument, and arguments that have type float are promoted to double. diff --git a/test/Sema/implicit-cast.c b/test/Sema/implicit-cast.c new file mode 100644 index 0000000000..fe83bd93e3 --- /dev/null +++ b/test/Sema/implicit-cast.c @@ -0,0 +1,8 @@ +// RUN: clang -fsyntax-only %s + +static char *test1(int cf) { + return cf ? "abc" : 0; +} +static char *test2(int cf) { + return cf ? 0 : "abc"; +} -- 2.50.1