From: Steve Naroff Date: Tue, 8 Jan 2008 01:11:38 +0000 (+0000) Subject: Fix Sema::CheckConditionalOperands(). The null pointer constant checks need to preced... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6d54e56a5c65c2728080578b84374c3c594daec;p=clang Fix Sema::CheckConditionalOperands(). The null pointer constant checks need to precede the check for two pointer operands. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45732 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index cff4908ede..7d224c5e80 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -788,7 +788,17 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 // C99 6.5.15p5: "If both operands have void type, the result has void type." if (lexT->isVoidType() && rexT->isVoidType()) return lexT.getUnqualifiedType(); - + + // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has + // the type of the other operand." + if (lexT->isPointerType() && rex->isNullPointerConstant(Context)) { + promoteExprToType(rex, lexT); // promote the null to a pointer. + return lexT; + } + if (rexT->isPointerType() && lex->isNullPointerConstant(Context)) { + promoteExprToType(lex, rexT); // promote the null to a pointer. + return rexT; + } // Handle the case where both operands are pointers before we handle null // pointer constants in case both operands are null pointer constants. if (const PointerType *LHSPT = lexT->getAsPointerType()) { // C99 6.5.15p3,6 @@ -822,18 +832,6 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 } } - // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has - // the type of the other operand." - if (lexT->isPointerType() && rex->isNullPointerConstant(Context)) { - promoteExprToType(rex, lexT); // promote the null to a pointer. - return lexT; - } - - if (rexT->isPointerType() && lex->isNullPointerConstant(Context)) { - promoteExprToType(lex, rexT); // promote the null to a pointer. - return rexT; - } - // Otherwise, the operands are not compatible. Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands, lexT.getAsString(), rexT.getAsString(), diff --git a/test/Sema/conditional-expr.c b/test/Sema/conditional-expr.c new file mode 100644 index 0000000000..f6b9d1f42d --- /dev/null +++ b/test/Sema/conditional-expr.c @@ -0,0 +1,17 @@ +// RUN: clang -fsyntax-only -verify -pedantic %s +void foo() { + *(0 ? (double *)0 : (void *)0) = 0; + *((void *) 0) = 0; // -expected-warning {{dereferencing void pointer}} -expected-error {{incomplete type 'void' is not assignable}} + double *dp; + int *ip; + void *vp; + + dp = vp; + vp = dp; + ip = dp; // -expected-warning {{incompatible pointer types assigning 'double *', expected 'int *'}} + dp = ip; // -expected-warning {{incompatible pointer types assigning 'int *', expected 'double *'}} + dp = 0 ? (double *)0 : (void *)0; + vp = 0 ? (double *)0 : (void *)0; + ip = 0 ? (double *)0 : (void *)0; // -expected-warning {{incompatible pointer types assigning 'double *', expected 'int *'}} +} +