Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -861,6 +861,8 @@ def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">; def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">; +def AtomicLibcall : DiagGroup<"atomic-libcall">; + // AddressSanitizer frontent instrumentation remarks. def SanitizeAddressRemarks : DiagGroup<"sanitize-address">; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -5120,6 +5120,8 @@ "_Atomic cannot be applied to " "%select{incomplete |array |function |reference |atomic |qualified |}0type " "%1 %select{||||||which is not trivially copyable}0">; +def warn_atomic_builtin_expands_to_libcall : Warning< + "atomic builtin expands to library call">, InGroup, DefaultIgnore; // Expressions. def ext_sizeof_alignof_function_type : Extension< Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3035,6 +3035,14 @@ ASTContext& Context = this->getASTContext(); + // Warn if the atomic will expand into a library call if requested. + TypeInfo ValueTI = Context.getTypeInfo(ValType); + uint64_t Size = ValueTI.Width; + uint64_t Align = ValueTI.Align; + if (!Context.getTargetInfo().hasBuiltinAtomic(Size, Align)) { + Diag(DRE->getLocStart(), diag::warn_atomic_builtin_expands_to_libcall); + } + // Create a new DeclRefExpr to refer to the new decl. DeclRefExpr* NewDRE = DeclRefExpr::Create( Context, Index: test/Sema/atomic-libcall.c =================================================================== --- /dev/null +++ test/Sema/atomic-libcall.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -triple=mips-mti-linux-gnu -Watomic-libcall + +// Test that larger than word size atomics are warned about. + +long long var; + +void foo(long long a) { + __sync_fetch_and_add(&var, 0, a); // expected-warning {{atomic builtin expands to library call}} +}