[cfe-commits] r172769 - in /cfe/trunk: include/clang/AST/EvaluatedExprVisitor.h include/clang/AST/Expr.h include/clang/Basic/Builtins.def include/clang/Basic/Builtins.h lib/AST/Expr.cpp test/SemaCXX/warn-unsequenced.cpp

Richard Smith richard-llvm at metafoo.co.uk
Thu Jan 17 15:46:04 PST 2013


Author: rsmith
Date: Thu Jan 17 17:46:04 2013
New Revision: 172769

URL: http://llvm.org/viewvc/llvm-project?rev=172769&view=rev
Log:
Some builtins do not evaluate their arguments. Teach EvaluatedExprVisitor not
to visit them.

Modified:
    cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Basic/Builtins.def
    cfe/trunk/include/clang/Basic/Builtins.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/test/SemaCXX/warn-unsequenced.cpp

Modified: cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h?rev=172769&r1=172768&r2=172769&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h (original)
+++ cfe/trunk/include/clang/AST/EvaluatedExprVisitor.h Thu Jan 17 17:46:04 2013
@@ -61,12 +61,17 @@
     // expressions.
     return this->Visit(E->getInit());
   }
-  
+
   void VisitCXXTypeidExpr(CXXTypeidExpr *E) {
     if (E->isPotentiallyEvaluated())
       return this->Visit(E->getExprOperand());
   }
-  
+
+  void VisitCallExpr(CallExpr *CE) {
+    if (!CE->isUnevaluatedBuiltinCall(Context))
+      return static_cast<ImplClass*>(this)->VisitExpr(CE);
+  }
+
   /// \brief The basis case walks all of the children of the statement or
   /// expression, assuming they are all potentially evaluated.
   void VisitStmt(Stmt *S) {

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=172769&r1=172768&r2=172769&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Jan 17 17:46:04 2013
@@ -2193,6 +2193,10 @@
   /// not, return 0.
   unsigned isBuiltinCall() const;
 
+  /// \brief Returns \c true if this is a call to a builtin which does not
+  /// evaluate side-effects within its arguments.
+  bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const;
+
   /// getCallReturnType - Get the return type of the call expr. This is not
   /// always the type of the expr itself, if the return type is a reference
   /// type.

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=172769&r1=172768&r2=172769&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Thu Jan 17 17:46:04 2013
@@ -82,6 +82,7 @@
 //          through an ellipsis
 //  e -> const, but only when -fmath-errno=0
 //  j -> returns_twice (like setjmp)
+//  u -> arguments are not evaluated for their side-effects
 //  FIXME: gcc has nonnull
 
 #if defined(BUILTIN) && !defined(LIBBUILTIN)
@@ -395,8 +396,8 @@
 BUILTIN(__builtin_bswap64, "ULLiULLi", "nc")
 
 // Random GCC builtins
-BUILTIN(__builtin_constant_p, "i.", "nct")
-BUILTIN(__builtin_classify_type, "i.", "nct")
+BUILTIN(__builtin_constant_p, "i.", "nctu")
+BUILTIN(__builtin_classify_type, "i.", "nctu")
 BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc")
 BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc")
 BUILTIN(__builtin_va_start, "vA.", "nt")
@@ -454,7 +455,7 @@
 BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
 
 // GCC Object size checking builtins
-BUILTIN(__builtin_object_size, "zvC*i", "n")
+BUILTIN(__builtin_object_size, "zvC*i", "nu")
 BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
 BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF")
 BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")

Modified: cfe/trunk/include/clang/Basic/Builtins.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.h?rev=172769&r1=172768&r2=172769&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.h (original)
+++ cfe/trunk/include/clang/Basic/Builtins.h Thu Jan 17 17:46:04 2013
@@ -109,6 +109,12 @@
     return strchr(GetRecord(ID).Attributes, 'j') != 0;
   }
 
+  /// \brief Returns true if this builtin does not perform the side-effects
+  /// of its arguments.
+  bool isUnevaluated(unsigned ID) const {
+    return strchr(GetRecord(ID).Attributes, 'u') != 0;
+  }
+
   /// \brief Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=172769&r1=172768&r2=172769&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Jan 17 17:46:04 2013
@@ -1137,6 +1137,12 @@
   return FDecl->getBuiltinID();
 }
 
+bool CallExpr::isUnevaluatedBuiltinCall(ASTContext &Ctx) const {
+  if (unsigned BI = isBuiltinCall())
+    return Ctx.BuiltinInfo.isUnevaluated(BI);
+  return false;
+}
+
 QualType CallExpr::getCallReturnType() const {
   QualType CalleeType = getCallee()->getType();
   if (const PointerType *FnTypePtr = CalleeType->getAs<PointerType>())

Modified: cfe/trunk/test/SemaCXX/warn-unsequenced.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unsequenced.cpp?rev=172769&r1=172768&r2=172769&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-unsequenced.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-unsequenced.cpp Thu Jan 17 17:46:04 2013
@@ -95,4 +95,9 @@
 
   xs[8] && (++a + a++); // expected-warning {{multiple unsequenced modifications}}
   xs[8] || (++a + a++); // expected-warning {{multiple unsequenced modifications}}
+
+  (__builtin_classify_type(++a) ? 1 : 0) + ++a; // ok
+  (__builtin_constant_p(++a) ? 1 : 0) + ++a; // ok
+  (__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok
+  (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
 }





More information about the cfe-commits mailing list