]> granicus.if.org Git - clang/commitdiff
Form a CallExpr from __noop without parens
authorReid Kleckner <reid@kleckner.net>
Fri, 11 Jul 2014 23:54:29 +0000 (23:54 +0000)
committerReid Kleckner <reid@kleckner.net>
Fri, 11 Jul 2014 23:54:29 +0000 (23:54 +0000)
MSVC accepts __noop without any trailing parens and treats it like a
literal zero.  We don't treat __noop as an integer literal, but now at
least we can parse a naked __noop expression.

Reviewers: rsmith

Differential Revision: http://reviews.llvm.org/D4476

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

lib/Sema/SemaExpr.cpp
test/CodeGen/builtin-ms-noop.cpp

index 67e839c7e592c21f4c3de66596ab4b0112533b36..8db782a7e2069b7a4c1cff4f9651cb7de9eb2072 100644 (file)
@@ -13477,9 +13477,22 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
   case BuiltinType::PseudoObject:
     return checkPseudoObjectRValue(E);
 
-  case BuiltinType::BuiltinFn:
+  case BuiltinType::BuiltinFn: {
+    // Accept __noop without parens by implicitly converting it to a call expr.
+    auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts());
+    if (DRE) {
+      auto *FD = cast<FunctionDecl>(DRE->getDecl());
+      if (FD->getBuiltinID() == Builtin::BI__noop) {
+        E = ImpCastExprToType(E, Context.getPointerType(FD->getType()),
+                              CK_BuiltinFnToFnPtr).get();
+        return new (Context) CallExpr(Context, E, None, Context.IntTy,
+                                      VK_RValue, SourceLocation());
+      }
+    }
+
     Diag(E->getLocStart(), diag::err_builtin_fn_use);
     return ExprError();
+  }
 
   // Everything else should be impossible.
 #define BUILTIN_TYPE(Id, SingletonId) \
index f5064fbf3c0b3131fb5f8cd1b80c3ff794613edd..76c6c139d00070f28ae891da13ef79abcb17a5b3 100644 (file)
@@ -1,13 +1,30 @@
-// RUN: %clang_cc1 -fms-extensions -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
 
-class A {
- public:
+struct A {
   ~A() {}
 };
 
-int f() {
-// CHECK: @_Z1fv
+extern "C" int f() {
+// CHECK: define i32 @f()
 // CHECK-NOT: call void @_ZN1AD1Ev
 // CHECK: ret i32 0
   return __noop(A());
 };
+
+extern "C" int g() {
+  return __noop;
+// CHECK: define i32 @g()
+// CHECK: ret i32 0
+}
+
+extern "C" int h() {
+  return (__noop);
+// CHECK: define i32 @h()
+// CHECK: ret i32 0
+}
+
+extern "C" int i() {
+  return __noop + 1;
+// CHECK: define i32 @i()
+// CHECK: ret i32 1
+}