Sema::CheckConditionalOperands(): Soften pointer/integer mismatch from error->warning.
Fixes <rdar://problem/6762239> [sema] gcc incompatibility; error on incompatible operand types in ?:. llvm-svn: 68617
This commit is contained in:
parent
3da1d240ff
commit
ea4c780da1
|
@ -1207,6 +1207,8 @@ def err_typecheck_cond_incompatible_operands : Error<
|
|||
"incompatible operand types (%0 and %1)">;
|
||||
def warn_typecheck_cond_incompatible_pointers : Warning<
|
||||
"pointer type mismatch (%0 and %1)">;
|
||||
def warn_typecheck_cond_pointer_integer_mismatch : Warning<
|
||||
"pointer/integer type mismatch in conditional expression (%0 and %1)">;
|
||||
def err_typecheck_choose_expr_requires_constant : Error<
|
||||
"'__builtin_choose_expr' requires a constant expression">;
|
||||
def ext_typecheck_expression_not_constant_but_accepted : Extension<
|
||||
|
|
|
@ -2714,6 +2714,20 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
|
|||
}
|
||||
}
|
||||
|
||||
// GCC compatibility: soften pointer/integer mismatch.
|
||||
if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
|
||||
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
|
||||
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
|
||||
ImpCastExprToType(LHS, RHSTy); // promote the integer to a pointer.
|
||||
return RHSTy;
|
||||
}
|
||||
if (LHSTy->isPointerType() && RHSTy->isIntegerType()) {
|
||||
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
|
||||
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
|
||||
ImpCastExprToType(RHS, LHSTy); // promote the integer to a pointer.
|
||||
return LHSTy;
|
||||
}
|
||||
|
||||
// Selection between block pointer types is ok as long as they are the same.
|
||||
if (LHSTy->isBlockPointerType() && RHSTy->isBlockPointerType() &&
|
||||
Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy))
|
||||
|
|
|
@ -40,3 +40,12 @@ int Postgresql() {
|
|||
char x;
|
||||
return ((((&x) != ((void *) 0)) ? (*(&x) = ((char) 1)) : (void) ((void *) 0)), (unsigned long) ((void *) 0)); // expected-warning {{C99 forbids conditional expressions with only one void side}}
|
||||
}
|
||||
|
||||
#define nil ((void*) 0)
|
||||
|
||||
extern int f1(void);
|
||||
|
||||
int f0(int a) {
|
||||
// GCC considers this a warning.
|
||||
return a ? f1() : nil; // expected-warning {{pointer/integer type mismatch in conditional expression ('int' and 'void *')}} expected-warning {{incompatible pointer to integer conversion returning 'void *', expected 'int'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue