summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2007-11-30 19:04:31 +0000
committerAnders Carlsson <andersca@mac.com>2007-11-30 19:04:31 +0000
commit801c5c74677fa615bbe5c18576f38499c8d3f82c (patch)
tree17ef3c0afa808787ceb103f2408e40f067f4e35d
parent907703cecddca73eaaa1c4d3c4fdf9ef8c9bd987 (diff)
downloadbcm5719-llvm-801c5c74677fa615bbe5c18576f38499c8d3f82c.tar.gz
bcm5719-llvm-801c5c74677fa615bbe5c18576f38499c8d3f82c.zip
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
-rw-r--r--clang/AST/Expr.cpp8
-rw-r--r--clang/Analysis/UninitializedValues.cpp8
-rw-r--r--clang/Sema/SemaChecking.cpp20
-rw-r--r--clang/test/Analysis/conditional-op-missing-lhs.c26
4 files changed, 50 insertions, 12 deletions
diff --git a/clang/AST/Expr.cpp b/clang/AST/Expr.cpp
index 682b4bd92be..0aee702c65d 100644
--- a/clang/AST/Expr.cpp
+++ b/clang/AST/Expr.cpp
@@ -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;
}
diff --git a/clang/Analysis/UninitializedValues.cpp b/clang/Analysis/UninitializedValues.cpp
index 8a27b71b8fd..35d6124e621 100644
--- a/clang/Analysis/UninitializedValues.cpp
+++ b/clang/Analysis/UninitializedValues.cpp
@@ -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) {
diff --git a/clang/Sema/SemaChecking.cpp b/clang/Sema/SemaChecking.cpp
index 20f0b81b430..81a18c9645f 100644
--- a/clang/Sema/SemaChecking.cpp
+++ b/clang/Sema/SemaChecking.cpp
@@ -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.
diff --git a/clang/test/Analysis/conditional-op-missing-lhs.c b/clang/test/Analysis/conditional-op-missing-lhs.c
new file mode 100644
index 00000000000..917212d3877
--- /dev/null
+++ b/clang/test/Analysis/conditional-op-missing-lhs.c
@@ -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];
+}
+
OpenPOWER on IntegriCloud