diff options
-rw-r--r-- | clang/Sema/SemaExpr.cpp | 24 | ||||
-rw-r--r-- | clang/test/Sema/conditional-expr.c | 17 |
2 files changed, 28 insertions, 13 deletions
diff --git a/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index cff4908edef..7d224c5e802 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/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/clang/test/Sema/conditional-expr.c b/clang/test/Sema/conditional-expr.c new file mode 100644 index 00000000000..f6b9d1f42da --- /dev/null +++ b/clang/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 *'}} +} + |