GCC has an extension where the left hand side of the ? : operator can be omitted. Handle this in a few more places.

llvm-svn: 44462
This commit is contained in:
Anders Carlsson 2007-11-30 19:04:31 +00:00
parent 907703cecd
commit 801c5c7467
4 changed files with 50 additions and 12 deletions

View File

@ -494,7 +494,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
case ConditionalOperatorClass: {
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
if (!Exp->getCond()->isConstantExpr(Ctx, Loc) ||
!Exp->getLHS()->isConstantExpr(Ctx, Loc) ||
// Handle the GNU extension for missing LHS.
!(Exp->getLHS() && Exp->getLHS()->isConstantExpr(Ctx, Loc)) ||
!Exp->getRHS()->isConstantExpr(Ctx, Loc))
return false;
return true;
@ -809,10 +810,11 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
if (Result == 0) std::swap(TrueExp, FalseExp);
// Evaluate the false one first, discard the result.
if (!FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
return false;
// Evalute the true one, capture the result.
if (!TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
if (TrueExp &&
!TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
return false;
break;
}

View File

@ -145,7 +145,13 @@ bool TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
bool TransferFuncs::VisitConditionalOperator(ConditionalOperator* C) {
Visit(C->getCond());
return Visit(C->getLHS()) & Visit(C->getRHS()); // Yes: we want &, not &&.
bool rhsResult = Visit(C->getRHS());
// Handle the GNU extension for missing LHS.
if (Expr *lhs = C->getLHS())
return Visit(lhs) & rhsResult; // Yes: we want &, not &&.
else
return rhsResult;
}
bool TransferFuncs::VisitStmt(Stmt* S) {

View File

@ -564,10 +564,12 @@ static DeclRefExpr* EvalAddr(Expr *E) {
case Stmt::ConditionalOperatorClass: {
ConditionalOperator *C = cast<ConditionalOperator>(E);
if (DeclRefExpr* LHS = EvalAddr(C->getLHS()))
return LHS;
else
return EvalAddr(C->getRHS());
// Handle the GNU extension for missing LHS.
if (Expr *lhsExpr = C->getLHS())
if (DeclRefExpr* LHS = EvalAddr(lhsExpr))
return LHS;
return EvalAddr(C->getRHS());
}
// For implicit casts, we need to handle conversions from arrays to
@ -674,10 +676,12 @@ static DeclRefExpr* EvalVal(Expr *E) {
// non-NULL DeclRefExpr's. If one is non-NULL, we return it.
ConditionalOperator *C = cast<ConditionalOperator>(E);
if (DeclRefExpr *LHS = EvalVal(C->getLHS()))
return LHS;
else
return EvalVal(C->getRHS());
// Handle the GNU extension for missing LHS.
if (Expr *lhsExpr = C->getLHS())
if (DeclRefExpr *LHS = EvalVal(lhsExpr))
return LHS;
return EvalVal(C->getRHS());
}
// Accesses to members are potential references to data on the stack.

View File

@ -0,0 +1,26 @@
// RUN: clang -warn-dead-stores -warn-uninit-values -verify %s
void f1()
{
int i;
int j = i ? : 1; // expected-warning{{use of uninitialized variable}}
}
void *f2(int *i)
{
return i ? : 0;
}
void *f3(int *i)
{
int a;
return &a ? : i;
}
void f4()
{
char c[1 ? : 2];
}