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