From 538bbe597b935a74d95c668ad209536753f13481 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 28 May 2013 17:37:39 +0000 Subject: [PATCH] Patch to issue error when target of MacOS and iOS does not support large load/store of atomic objects. // rdar://13973577 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182781 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 2 ++ include/clang/Basic/DiagnosticSemaKinds.td | 4 +++ lib/AST/ASTContext.cpp | 14 ++++++++++ lib/Sema/SemaChecking.cpp | 14 +++++++--- test/CodeGen/atomic-ops.c | 7 +---- test/Sema/atomic-requires-library-error.c | 31 ++++++++++++++++++++++ 6 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 test/Sema/atomic-requires-library-error.c diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 94dad6bbc3..b69a4f4525 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -470,6 +470,8 @@ public: const TargetInfo &getTargetInfo() const { return *Target; } + bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const; + const LangOptions& getLangOpts() const { return LangOpts; } DiagnosticsEngine &getDiagnostics() const; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index f64df9c6b4..130f729a60 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -5322,6 +5322,10 @@ def err_atomic_op_needs_atomic_int_or_ptr : Error< def err_atomic_op_bitwise_needs_atomic_int : Error< "first argument to bitwise atomic operation must be a pointer to " "%select{|atomic }0integer (%1 invalid)">; + +def err_atomic_load_store_uses_lib : Error< + "atomic %select{load|store}0 requires runtime support that is not " + "available for this target">; def err_deleted_function_use : Error<"attempt to use a deleted function">; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f5e4b42d27..946d3df86c 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -8030,3 +8030,17 @@ unsigned ASTContext::getParameterIndex(const ParmVarDecl *D) const { "ParmIndices lacks entry set by ParmVarDecl"); return I->second; } + +bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const { + const llvm::Triple &T = getTargetInfo().getTriple(); + if (!T.isOSDarwin()) + return false; + + QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); + CharUnits sizeChars = getTypeSizeInChars(AtomicTy); + uint64_t Size = sizeChars.getQuantity(); + CharUnits alignChars = getTypeAlignInChars(AtomicTy); + unsigned Align = alignChars.getQuantity(); + unsigned MaxInlineWidthInBits = getTargetInfo().getMaxAtomicInlineWidth(); + return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits); +} diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index cdc546c476..da24667804 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -908,10 +908,18 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, SubExprs.push_back(TheCall->getArg(3)); // Weak break; } + + AtomicExpr *AE = new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(), + SubExprs, ResultType, Op, + TheCall->getRParenLoc()); + + if ((Op == AtomicExpr::AO__c11_atomic_load || + (Op == AtomicExpr::AO__c11_atomic_store)) && + Context.AtomicUsesUnsupportedLibcall(AE)) + Diag(AE->getLocStart(), diag::err_atomic_load_store_uses_lib) << + ((Op == AtomicExpr::AO__c11_atomic_load) ? 0 : 1); - return Owned(new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(), - SubExprs, ResultType, Op, - TheCall->getRParenLoc())); + return Owned(AE); } diff --git a/test/CodeGen/atomic-ops.c b/test/CodeGen/atomic-ops.c index d79f405223..830f21a569 100644 --- a/test/CodeGen/atomic-ops.c +++ b/test/CodeGen/atomic-ops.c @@ -246,9 +246,6 @@ _Atomic(struct foo) bigAtomic; void structAtomicStore() { // CHECK: @structAtomicStore struct foo f = {0}; - __c11_atomic_store(&bigAtomic, f, 5); - // CHECK: call void @__atomic_store(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), - struct bar b = {0}; __atomic_store(&smallThing, &b, 5); // CHECK: call void @__atomic_store(i32 3, i8* {{.*}} @smallThing @@ -258,13 +255,11 @@ void structAtomicStore() { } void structAtomicLoad() { // CHECK: @structAtomicLoad - struct foo f = __c11_atomic_load(&bigAtomic, 5); - // CHECK: call void @__atomic_load(i32 512, i8* bitcast ({{.*}} @bigAtomic to i8*), - struct bar b; __atomic_load(&smallThing, &b, 5); // CHECK: call void @__atomic_load(i32 3, i8* {{.*}} @smallThing + struct foo f = {0}; __atomic_load(&bigThing, &f, 5); // CHECK: call void @__atomic_load(i32 512, i8* {{.*}} @bigThing } diff --git a/test/Sema/atomic-requires-library-error.c b/test/Sema/atomic-requires-library-error.c new file mode 100644 index 0000000000..b0aa278354 --- /dev/null +++ b/test/Sema/atomic-requires-library-error.c @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -triple=i686-apple-darwin9 -verify +// rdar://13973577 + +struct foo { + int big[128]; +}; +struct bar { + char c[3]; +}; + +struct bar smallThing; +struct foo bigThing; +_Atomic(struct foo) bigAtomic; + +void structAtomicStore() { + struct foo f = {0}; + __c11_atomic_store(&bigAtomic, f, 5); // expected-error {{atomic store requires runtime support that is not available for this target}} + + struct bar b = {0}; + __atomic_store(&smallThing, &b, 5); + + __atomic_store(&bigThing, &f, 5); +} + +void structAtomicLoad() { + struct foo f = __c11_atomic_load(&bigAtomic, 5); // expected-error {{atomic load requires runtime support that is not available for this target}} + struct bar b; + __atomic_load(&smallThing, &b, 5); + + __atomic_load(&bigThing, &f, 5); +} -- 2.40.0