"change the argument to be the free space in the destination buffer minus "
"the terminating null byte">;
+def warn_assume_side_effects : Warning<
+ "the argument to __assume has side effects that will be discarded">,
+ InGroup<DiagGroup<"assume">>;
+
/// main()
// static main() is not an error in C, just in C++.
def warn_static_main : Warning<"'main' should not be declared static">,
private:
bool SemaBuiltinPrefetch(CallExpr *TheCall);
+ bool SemaBuiltinAssume(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
if (SemaBuiltinPrefetch(TheCall))
return ExprError();
break;
+ case Builtin::BI__assume:
+ if (SemaBuiltinAssume(TheCall))
+ return ExprError();
+ break;
case Builtin::BI__builtin_object_size:
if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
return ExprError();
return false;
}
+/// SemaBuiltinAssume - Handle __assume (MS Extension).
+// __assume does not evaluate its arguments, and should warn if its argument
+// has side effects.
+bool Sema::SemaBuiltinAssume(CallExpr *TheCall) {
+ Expr *Arg = TheCall->getArg(0);
+ if (Arg->isInstantiationDependent()) return false;
+
+ if (Arg->HasSideEffects(Context))
+ return Diag(Arg->getLocStart(), diag::warn_assume_side_effects)
+ << Arg->getSourceRange();
+
+ return false;
+}
+
/// SemaBuiltinConstantArg - Handle a check if argument ArgNum of CallExpr
/// TheCall is a constant expression.
bool Sema::SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
--- /dev/null
+// RUN: %clang_cc1 -triple i386-mingw32 -fms-extensions -fsyntax-only -verify %s
+
+int foo(int *a, int i) {
+ __assume(i != 4);
+ __assume(++i > 2); //expected-warning {{the argument to __assume has side effects that will be discarded}}
+ return a[i];
+}
+