[cfe-commits] r39682 - in /cfe/cfe/trunk: AST/Expr.cpp Sema/Sema.h Sema/SemaStmt.cpp include/clang/AST/Expr.h include/clang/Basic/DiagnosticKinds.def
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:47:06 PDT 2007
Author: clattner
Date: Wed Jul 11 11:47:06 2007
New Revision: 39682
URL: http://llvm.org/viewvc/llvm-project?rev=39682&view=rev
Log:
First cut at warning about expressions whose results are ignored. For example,
this produces:
warn.c:4:3: warning: expression result unused
X == Y;
^~~~~~
warn.c:5:3: warning: expression result unused
(void)X;
^~~~~~~
warn.c:11:3: warning: expression result unused
A == foo(1, 2);
^~~~~~~~~~~~~~
warn.c:13:3: warning: expression result unused
foo(1,2)+foo(4,3);
^~~~~~~~~~~~~~~~~
Modified:
cfe/cfe/trunk/AST/Expr.cpp
cfe/cfe/trunk/Sema/Sema.h
cfe/cfe/trunk/Sema/SemaStmt.cpp
cfe/cfe/trunk/include/clang/AST/Expr.h
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Expr.cpp?rev=39682&r1=39681&r2=39682&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Expr.cpp (original)
+++ cfe/cfe/trunk/AST/Expr.cpp Wed Jul 11 11:47:06 2007
@@ -122,6 +122,61 @@
}
}
+
+//===----------------------------------------------------------------------===//
+// Generic Expression Routines
+//===----------------------------------------------------------------------===//
+
+/// hasLocalSideEffect - Return true if this immediate expression has side
+/// effects, not counting any sub-expressions.
+bool Expr::hasLocalSideEffect() const {
+ switch (getStmtClass()) {
+ default:
+ return false;
+ case ParenExprClass:
+ return cast<ParenExpr>(this)->getSubExpr()->hasLocalSideEffect();
+ case UnaryOperatorClass: {
+ const UnaryOperator *UO = cast<UnaryOperator>(this);
+
+ switch (UO->getOpcode()) {
+ default: return false;
+ case UnaryOperator::PostInc:
+ case UnaryOperator::PostDec:
+ case UnaryOperator::PreInc:
+ case UnaryOperator::PreDec:
+ return true; // ++/--
+
+ // FIXME: real/imag volatile
+ // deref volatile;
+
+ case UnaryOperator::Extension:
+ return UO->getSubExpr()->hasLocalSideEffect();
+ }
+ }
+ case BinaryOperatorClass:
+ return cast<BinaryOperator>(this)->isAssignmentOp();
+
+ case ArraySubscriptExprClass:
+ // volatile
+ return false;
+
+ case CallExprClass:
+ // TODO: check attributes for pure/const.
+ return true;
+
+ case MemberExprClass:
+ // volatile load.
+ return false;
+
+ case CastExprClass:
+ // If this is a cast to void, check the operand. Otherwise, the result of
+ // the cast is unused.
+ if (getType()->isVoidType())
+ return cast<CastExpr>(this)->getSubExpr()->hasLocalSideEffect();
+ return false;
+ }
+}
+
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or an
/// incomplete type other than void. Nonarray expressions that can be lvalues:
/// - name, where name must be a variable
@@ -172,10 +227,10 @@
isLvalueResult lvalResult = isLvalue();
switch (lvalResult) {
- case LV_Valid: break;
- case LV_NotObjectType: return MLV_NotObjectType;
- case LV_IncompleteVoidType: return MLV_IncompleteVoidType;
- case LV_InvalidExpression: return MLV_InvalidExpression;
+ case LV_Valid: break;
+ case LV_NotObjectType: return MLV_NotObjectType;
+ case LV_IncompleteVoidType: return MLV_IncompleteVoidType;
+ case LV_InvalidExpression: return MLV_InvalidExpression;
}
if (TR.isConstQualified())
return MLV_ConstQualified;
Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39682&r1=39681&r2=39682&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:47:06 2007
@@ -157,6 +157,8 @@
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.
public:
+ virtual StmtResult ParseExprStmt(ExprTy *Expr);
+
virtual StmtResult ParseNullStmt(SourceLocation SemiLoc);
virtual StmtResult ParseCompoundStmt(SourceLocation L, SourceLocation R,
StmtTy **Elts, unsigned NumElts);
Modified: cfe/cfe/trunk/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaStmt.cpp?rev=39682&r1=39681&r2=39682&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaStmt.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaStmt.cpp Wed Jul 11 11:47:06 2007
@@ -20,6 +20,19 @@
#include "clang/Lex/IdentifierTable.h"
using namespace clang;
+Sema::StmtResult Sema::ParseExprStmt(ExprTy *expr) {
+ Expr *E = static_cast<Expr*>(expr);
+
+ // Exprs are statements, so there is no need to do a conversion here. However,
+ // diagnose some potentially bad code.
+ if (!E->hasLocalSideEffect())
+ Diag(E->getLocStart()/*
+ getExprLoc()*/, diag::warn_unused_expr, E->getSourceRange());
+
+ return E;
+}
+
+
Sema::StmtResult Sema::ParseNullStmt(SourceLocation SemiLoc) {
return new NullStmt(SemiLoc);
}
Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39682&r1=39681&r2=39682&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:47:06 2007
@@ -42,6 +42,10 @@
SourceLocation getLocStart() const { return getSourceRange().Begin(); }
SourceLocation getLocEnd() const { return getSourceRange().End(); }
+ /// hasLocalSideEffect - Return true if this immediate expression has side
+ /// effects, not counting any sub-expressions.
+ bool hasLocalSideEffect() const;
+
/// isLvalue - C99 6.3.2.1: an lvalue is an expression with an object type or
/// incomplete type other than void. Nonarray expressions that can be lvalues:
/// - name, where name must be a variable
@@ -114,6 +118,7 @@
const Decl *getDecl() const { return D; }
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
+
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass;
@@ -400,6 +405,7 @@
Expr *getBase() const { return Base; }
FieldDecl *getMemberDecl() const { return MemberDecl; }
bool isArrow() const { return IsArrow; }
+
virtual SourceRange getSourceRange() const {
return SourceRange(getBase()->getLocStart(), MemberLoc);
}
@@ -426,6 +432,7 @@
QualType getDestType() const { return Ty; }
Expr *getSubExpr() const { return Op; }
+
virtual SourceRange getSourceRange() const {
return SourceRange(Loc, getSubExpr()->getSourceRange().End());
}
@@ -484,7 +491,6 @@
bool isLogicalOp() const { return Opc == LAnd || Opc == LOr; }
bool isAssignmentOp() const { return Opc >= Assign && Opc <= OrAssign; }
-
virtual void visit(StmtVisitor &Visitor);
static bool classof(const Stmt *T) {
return T->getStmtClass() == BinaryOperatorClass;
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39682&r1=39681&r2=39682&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:47:06 2007
@@ -633,6 +633,9 @@
DIAG(ext_typecheck_cond_incompatible_pointers, EXTENSION,
"pointer type mismatch ('%0' and '%1')")
+DIAG(warn_unused_expr, WARNING,
+ "expression result unused")
+
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
"'continue' statement not in loop statement")
More information about the cfe-commits
mailing list