]> granicus.if.org Git - clang/commitdiff
Add an __assume side-effects warning
authorHal Finkel <hfinkel@anl.gov>
Thu, 17 Jul 2014 14:25:55 +0000 (14:25 +0000)
committerHal Finkel <hfinkel@anl.gov>
Thu, 17 Jul 2014 14:25:55 +0000 (14:25 +0000)
In MS-compatibility mode, we support the __assume builtin. The __assume builtin
does not evaluate its arguments, and we should issue a warning if __assume is
provided with an argument with side effects (because these effects will be
discarded).

This is similar in spirit to the warnings issued by other compilers (Intel
Diagnostic 2261, MS Compiler Warning C4557).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@213266 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaChecking.cpp
test/Sema/builtin-assume.c [new file with mode: 0644]

index 4e77ec7dd20587b14aef2f4cf94a912da67e8e65..990ea283d52bc3834e0dfdc0c47a1b42525d934d 100644 (file)
@@ -444,6 +444,10 @@ def note_strncat_wrong_size : Note<
   "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">,
index 0ca5a545a7bdce32144ca78f157e29715b2c08be..4a6fe354cca80f806df2876e77bb745b3f961ab5 100644 (file)
@@ -8261,6 +8261,7 @@ public:
 
 private:
   bool SemaBuiltinPrefetch(CallExpr *TheCall);
+  bool SemaBuiltinAssume(CallExpr *TheCall);
   bool SemaBuiltinLongjmp(CallExpr *TheCall);
   ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
   ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
index 7a23797d477f795875858bbe8ee45a80e828f0c2..d8b801bf0a692ec7986bdd81932d789d912da8f5 100644 (file)
@@ -175,6 +175,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
     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();
@@ -1953,6 +1957,20 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
   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,
diff --git a/test/Sema/builtin-assume.c b/test/Sema/builtin-assume.c
new file mode 100644 (file)
index 0000000..6c83b69
--- /dev/null
@@ -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];
+}
+