Minor fixes of test and MarkDeclRefReferenced function.

http://reviews.llvm.org/D9000

Files:
  include/clang/Basic/Builtins.def
  include/clang/Sema/Sema.h
  lib/AST/ExprConstant.cpp
  lib/Parse/ParseExpr.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaExpr.cpp
  test/CodeGen/builtin-ms-noop.cpp
  test/Sema/builtin-ms-noop-errors.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def
+++ include/clang/Basic/Builtins.def
@@ -710,7 +710,7 @@
 LANGBUILTIN(_InterlockedExchange,        "LiLiD*Li",   "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*",   "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(_InterlockedIncrement,       "LiLiD*",     "n", ALL_MS_LANGUAGES)
-LANGBUILTIN(__noop,           "i.",  "n", ALL_MS_LANGUAGES)
+LANGBUILTIN(__noop,           "i.",  "tn", ALL_MS_LANGUAGES)
 LANGBUILTIN(__readfsdword,    "ULiULi", "n", ALL_MS_LANGUAGES)
 LANGBUILTIN(__va_start,       "vc**.", "nt", ALL_MS_LANGUAGES)
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -6446,6 +6446,24 @@
   /// to implement it anywhere else.
   ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
 
+  /// \brief This indicator indicates if current parsing is doing
+  /// inside arguments of __noop builtin.
+  bool InsideNoop;
+
+  /// \brief RAII object used to change InsideNoop indicator.
+  class InsideNoopRAII {
+    Sema &Self;
+    bool OldInsideNoop;
+
+  public:
+    InsideNoopRAII(Sema &Self, bool NewInsideNoop)
+        : Self(Self), OldInsideNoop(Self.InsideNoop) {
+      Self.InsideNoop = NewInsideNoop || Self.InsideNoop;
+    }
+
+    ~InsideNoopRAII() { Self.InsideNoop = OldInsideNoop; }
+  };
+
   /// \brief The current index into pack expansion arguments that will be
   /// used for substitution of parameter packs.
   ///
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -6228,6 +6228,9 @@
   default:
     return ExprEvaluatorBaseTy::VisitCallExpr(E);
 
+  case Builtin::BI__noop:
+    return Success(0, E);
+
   case Builtin::BI__builtin_object_size: {
     if (TryEvaluateBuiltinObjectSize(E))
       return true;
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -1468,6 +1468,17 @@
 
       if (OpKind == tok::l_paren || !LHS.isInvalid()) {
         if (Tok.isNot(tok::r_paren)) {
+          unsigned BuiltinId = 0;
+          if (LHS.isUsable()) {
+            Expr *Fn = LHS.get()->IgnoreParens();
+            if (DeclRefExpr *DRE = dyn_cast_or_null<DeclRefExpr>(Fn)) {
+              FunctionDecl *FnDecl =
+                  dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
+              BuiltinId = (FnDecl ? FnDecl->getBuiltinID() : 0);
+            }
+          }
+          Sema::InsideNoopRAII SubstIndex(Actions,
+                                          BuiltinId == Builtin::BI__noop);
           if (ParseExpressionList(ArgExprs, CommaLocs, [&] {
                 Actions.CodeCompleteCall(getCurScope(), LHS.get(), ArgExprs);
              })) {
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -101,11 +101,11 @@
     NumSFINAEErrors(0),
     CachedFakeTopLevelModule(nullptr),
     AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
-    NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
-    CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
-    TyposCorrected(0), AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr),
-    VarDataSharingAttributesStack(nullptr), CurScope(nullptr),
-    Ident_super(nullptr), Ident___float128(nullptr)
+    NonInstantiationEntries(0), InsideNoop(false),
+    ArgumentPackSubstitutionIndex(-1), CurrentInstantiationScope(nullptr),
+    DisableTypoCorrection(false), TyposCorrected(0), AnalysisWarnings(*this),
+    ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr),
+    CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr)
 {
   TUScope = nullptr;
 
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -337,6 +337,9 @@
     if (checkArgCount(*this, TheCall, 1)) return true;
     TheCall->setType(Context.IntTy);
     break;
+  case Builtin::BI__noop:
+    TheCall->setType(Context.IntTy);
+    break;
   case Builtin::BI__sync_fetch_and_add:
   case Builtin::BI__sync_fetch_and_add_1:
   case Builtin::BI__sync_fetch_and_add_2:
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -13227,6 +13227,13 @@
 
 /// \brief Perform reference-marking and odr-use handling for a DeclRefExpr.
 void Sema::MarkDeclRefReferenced(DeclRefExpr *E) {
+  // If we are inside call of __noop intrinsic we shouldn't mark function as
+  // referenced. We do so not to instantiate template functions. However we
+  // should mark variables as usual to avoid warnings about unused variables.
+  // This behaviour is the same as Microsoft compiler behaviour.
+  if (InsideNoop && isa<FunctionDecl>(E->getDecl()))
+    return;
+
   // TODO: update this with DR# once a defect report is filed.
   // C++11 defect. The address of a pure member should not be an ODR use, even
   // if it's a qualified reference.
Index: test/CodeGen/builtin-ms-noop.cpp
===================================================================
--- test/CodeGen/builtin-ms-noop.cpp
+++ test/CodeGen/builtin-ms-noop.cpp
@@ -4,6 +4,8 @@
   ~A() {}
 };
 
+int *p;
+
 extern "C" int f() {
 // CHECK: define i32 @f()
 // CHECK-NOT: call void @_ZN1AD1Ev
@@ -28,3 +30,9 @@
 // CHECK: define i32 @i()
 // CHECK: ret i32 1
 }
+
+extern "C" void j() {
+  p = __noop;
+// CHECK: define void @j()
+// CHECK: store i32* null, i32** @p
+}
Index: test/Sema/builtin-ms-noop-errors.cpp
===================================================================
--- test/Sema/builtin-ms-noop-errors.cpp
+++ test/Sema/builtin-ms-noop-errors.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fms-compatibility -Wunused -verify %s
+
+class A {
+public:
+  ~A(){};
+};
+template<typename T> static A function1(int a) { sdklfj sdfjsd sdfksdf }
+template<typename T> static int function2() { fwedq rfgr dfgsdg }
+template<typename T> int function3(int a) { fwedq rfgr dfgsdg }
+int Z(){return 0;}
+int Z1(int){return 0;}
+void Z2(){}
+
+void D1() {
+  int var1, var2, var3, var4, var5, var6, var7, var8;
+  ((__noop))(function2<void>());
+  __noop(Z(), Z(), (function2<int>()), Z1(function2<int>()));
+  __noop(Z2());
+  __noop(function2<void>() + var1 + var2);
+  __noop(function1<int>(var3));
+  __noop(function2<int>() + Z1(var4) - function3<float>(var5));
+  __noop(function1<void>(function3<int>(__noop(var6 + function3<int>(var7)))));
+  __noop(function1<int>(Z1(var8)));
+}
+
+int D2() {
+  int arr[] = {9,8,7,6,5,4,3,2,1,0};
+  int T2 = arr[__noop() + 1];
+  int T3 = arr[__noop + 2];
+  return T2 + T3;
+}
+
+int D3() {
+  class A {};
+  int *A1 = __noop; // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+  int *A2 = __noop(); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+  int *A3;
+  A3 = __noop; // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+  A3 = __noop(); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
+  int (*A4)() = __noop; // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int (*)()'}}
+  int (*A5)();
+  A5 = __noop; // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int (*)()'}}
+  void (*A6)();
+  A6 = __noop; // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'void (*)()'}}
+  const int (*A7)(const float);
+  A7 = __noop(2); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'const int (*)(const float)'}}
+  void (A::*A8)();
+  A8 = __noop;
+  return A1[0] + A2[0] + A3[0] + A4() + A5();
+}
+
+void D4() {
+  int arr[10];
+  int T1 = arr[__noop(4 asdfasdf^*^&$^, 5) + __noop]; //expected-error{{expected ')'}} expected-note{{to match this '('}}
+  &__noop; // expected-error{{cannot take the address of an rvalue of type 'int'}}
+  &__noop(); // expected-error{{cannot take the address of an rvalue of type 'int'}}
+  int A = __noop[5]; // expected-error{{subscripted value is not an array, pointer, or vector}}
+  int __noop = 10;
+  int A1 = __noop(); // expected-error{{called object type 'int' is not a function or function pointer}}
+}
+
+int D5() {
+  int a1 = __noop(42, 56);
+  int a2 = __noop;
+  int a3; a3 = __noop(5);
+  int a4 = (__noop)();
+  int a5 = (__noop);
+  int a6 = (__noop());
+  int a7 = ((__noop)(5));
+  int a8 = ((__noop))();
+  return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
+}
+
+int D7() {
+  __noop;
+  __noop();
+  int T1 = __noop;
+  int T2 = __noop();
+  int __noop = 12;
+  int *A = &__noop;
+  int T3 = __noop;
+  int T4 = *A;
+  return T1 + T2 + T3 + T4;
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to