Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -444,6 +444,10 @@ "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>; + /// main() // static main() is not an error in C, just in C++. def warn_static_main : Warning<"'main' should not be declared static">, Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -8244,6 +8244,7 @@ private: bool SemaBuiltinPrefetch(CallExpr *TheCall); + bool SemaBuiltinAssume(CallExpr *TheCall); bool SemaBuiltinLongjmp(CallExpr *TheCall); ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult); ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult, Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -175,6 +175,10 @@ 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(); @@ -1942,6 +1946,20 @@ 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->isTypeDependent() || Arg->isValueDependent()) 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, Index: test/Sema/builtin-assume.c =================================================================== --- /dev/null +++ test/Sema/builtin-assume.c @@ -0,0 +1,8 @@ +// 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]; +} +