jansvoboda11 updated this revision to Diff 435448. jansvoboda11 added a comment.
Handle volatile _Atomic as well Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D125349/new/ https://reviews.llvm.org/D125349 Files: clang/lib/Sema/SemaOverload.cpp clang/test/CodeGenCXX/atomic-builtin-compound-assignment-overload.cpp clang/test/SemaCXX/atomic-builtin-compound-assignment-overload.cpp
Index: clang/test/SemaCXX/atomic-builtin-compound-assignment-overload.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/atomic-builtin-compound-assignment-overload.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -std=gnu++98 -fsyntax-only -verify %s +// expected-no-diagnostics + +_Atomic unsigned an_atomic_uint; + +enum { an_enum_value = 1 }; + +void enum1() { an_atomic_uint += an_enum_value; } + +void enum2() { an_atomic_uint |= an_enum_value; } + +volatile _Atomic unsigned an_volatile_atomic_uint; + +void enum3() { an_volatile_atomic_uint += an_enum_value; } + +void enum4() { an_volatile_atomic_uint |= an_enum_value; } Index: clang/test/CodeGenCXX/atomic-builtin-compound-assignment-overload.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/atomic-builtin-compound-assignment-overload.cpp @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 -std=gnu++11 -emit-llvm -triple=x86_64-linux-gnu -o - %s | FileCheck %s + +_Atomic unsigned an_atomic_uint; + +enum { an_enum_value = 1 }; + +// CHECK-LABEL: define {{.*}}void @_Z5enum1v() +void enum1() { + an_atomic_uint += an_enum_value; + // CHECK: atomicrmw add ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum2v() +void enum2() { + an_atomic_uint |= an_enum_value; + // CHECK: atomicrmw or ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum3RU7_Atomicj({{.*}}) +void enum3(_Atomic unsigned &an_atomic_uint_param) { + an_atomic_uint_param += an_enum_value; + // CHECK: atomicrmw add ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum4RU7_Atomicj({{.*}}) +void enum4(_Atomic unsigned &an_atomic_uint_param) { + an_atomic_uint_param |= an_enum_value; + // CHECK: atomicrmw or ptr +} + +volatile _Atomic unsigned an_volatile_atomic_uint; + +// CHECK-LABEL: define {{.*}}void @_Z5enum5v() +void enum5() { + an_volatile_atomic_uint += an_enum_value; + // CHECK: atomicrmw add ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum6v() +void enum6() { + an_volatile_atomic_uint |= an_enum_value; + // CHECK: atomicrmw or ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum7RVU7_Atomicj({{.*}}) +void enum7(volatile _Atomic unsigned &an_volatile_atomic_uint_param) { + an_volatile_atomic_uint_param += an_enum_value; + // CHECK: atomicrmw add ptr +} + +// CHECK-LABEL: define {{.*}}void @_Z5enum8RVU7_Atomicj({{.*}}) +void enum8(volatile _Atomic unsigned &an_volatile_atomic_uint_param) { + an_volatile_atomic_uint_param |= an_enum_value; + // CHECK: atomicrmw or ptr +} Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -8202,6 +8202,7 @@ Sema &S; ArrayRef<Expr *> Args; Qualifiers VisibleTypeConversionsQuals; + bool VisibleTypeIsAtomic; bool HasArithmeticOrEnumeralCandidateType; SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes; OverloadCandidateSet &CandidateSet; @@ -8326,11 +8327,13 @@ BuiltinOperatorOverloadBuilder( Sema &S, ArrayRef<Expr *> Args, Qualifiers VisibleTypeConversionsQuals, + bool VisibleTypeIsAtomic, bool HasArithmeticOrEnumeralCandidateType, SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes, OverloadCandidateSet &CandidateSet) : S(S), Args(Args), VisibleTypeConversionsQuals(VisibleTypeConversionsQuals), + VisibleTypeIsAtomic(VisibleTypeIsAtomic), HasArithmeticOrEnumeralCandidateType( HasArithmeticOrEnumeralCandidateType), CandidateTypes(CandidateTypes), @@ -8951,12 +8954,27 @@ S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); + if (VisibleTypeIsAtomic) { + ParamTypes[0] = S.Context.getAtomicType(LeftBaseTy); + ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); + S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, + /*IsAssignmentOperator=*/isEqualOp); + } + // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(LeftBaseTy); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/isEqualOp); + + if (VisibleTypeIsAtomic) { + ParamTypes[0] = S.Context.getAtomicType(LeftBaseTy); + ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); + ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); + S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, + /*IsAssignmentOperator=*/isEqualOp); + } } } } @@ -9007,12 +9025,26 @@ // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(LeftBaseTy); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); + + if (VisibleTypeIsAtomic) { + ParamTypes[0] = S.Context.getAtomicType(LeftBaseTy); + ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); + S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); + } + if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). ParamTypes[0] = LeftBaseTy; ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); + + if (VisibleTypeIsAtomic) { + ParamTypes[0] = S.Context.getAtomicType(LeftBaseTy); + ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); + ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); + S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); + } } } } @@ -9179,8 +9211,11 @@ // candidate types or either arithmetic or enumeral candidate types. Qualifiers VisibleTypeConversionsQuals; VisibleTypeConversionsQuals.addConst(); - for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) + bool VisibleTypeIsAtomic = false; + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]); + VisibleTypeIsAtomic |= Args[ArgIdx]->getType()->isAtomicType(); + } bool HasNonRecordCandidateType = false; bool HasArithmeticOrEnumeralCandidateType = false; @@ -9213,6 +9248,7 @@ // Setup an object to manage the common state for building overloads. BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, VisibleTypeConversionsQuals, + VisibleTypeIsAtomic, HasArithmeticOrEnumeralCandidateType, CandidateTypes, CandidateSet);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits