[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