[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