Author: mkovacevic99
Date: 2026-06-29T08:36:28Z
New Revision: 114730b54371bf1dfb09a437564207185128665b

URL: 
https://github.com/llvm/llvm-project/commit/114730b54371bf1dfb09a437564207185128665b
DIFF: 
https://github.com/llvm/llvm-project/commit/114730b54371bf1dfb09a437564207185128665b.diff

LOG: [Clang] Handle deduced auto types within AtomicType (#197874)

This patch fixes handling of deduced types nested inside AtomicType.

Previously, GetContainedDeducedTypeVisitor did not recurse through
AtomicType nodes, causing getContainedDeducedType() to incorrectly
return null for types such as:

**_Atomic(__auto_type)**

As a result, undeduced AutoType instances could bypass semantic checks
and later reach codegen/type layout paths, eventually triggering
assertions such as:

_!A->getDeducedType().isNull() && "cannot request the size of an
undeduced or dependent auto type_

This patch adds AtomicType traversal support to
GetContainedDeducedTypeVisitor so contained deduced types are properly
discovered.

Additionally, template deduction logic for AtomicType is extended to
allow deduction from the atomic value type when the pattern contains an
auto type.

CheckOriginalCallArgDeduction is also adjusted to handle atomic wrappers
around deduced types correctly.

This brings Clang behavior closer to GCC for combinations involving
_Atomic and __auto_type and prevents undeduced auto types from escaping
into later compilation stages.

---------

Fixes #118058

Added: 
    clang/test/CodeGen/atomic-auto-type.c
    clang/test/Sema/atomic-auto-type.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/Type.cpp
    clang/lib/Sema/SemaTemplateDeduction.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4337b20e59070..05c28aa069d34 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -1070,6 +1070,9 @@ Crash and bug fixes
 
 - Fixed ``security.VAList`` checker producing false positives when analyzing
   C23 code where ``va_start`` expands to ``__builtin_c23_va_start``.
+  
+- Fixed a compiler crash when combining ``_Atomic`` and ``__auto_type``
+  in C, for example ``_Atomic __auto_type x = expr``. (#GH118058)
 
 Improvements
 ^^^^^^^^^^^^

diff  --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index dffb3f1b50207..19b85d0e0af69 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2102,6 +2102,10 @@ class GetContainedDeducedTypeVisitor
   Type *VisitPackExpansionType(const PackExpansionType *T) {
     return Visit(T->getPattern());
   }
+
+  Type *VisitAtomicType(const AtomicType *T) {
+    return Visit(T->getValueType());
+  }
 };
 
 } // namespace

diff  --git a/clang/lib/Sema/SemaTemplateDeduction.cpp 
b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 26c397afdd6ef..d93b528facbcc 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3741,8 +3741,10 @@ CheckOriginalCallArgDeduction(Sema &S, 
TemplateDeductionInfo &Info,
   QualType A = OriginalArg.OriginalArgType;
   QualType OriginalParamType = OriginalArg.OriginalParamType;
 
-  // Check for type equality (top-level cv-qualifiers are ignored).
-  if (Context.hasSameUnqualifiedType(A, DeducedA))
+  // Check for type equality (top-level cv-qualifiers and _Atomic are ignored,
+  // since _Atomic is treated as a qualifier).
+  if (Context.hasSameType(A.getAtomicUnqualifiedType(),
+                          DeducedA.getAtomicUnqualifiedType()))
     return TemplateDeductionResult::Success;
 
   // Strip off references on the argument types; they aren't needed for
@@ -5112,6 +5114,25 @@ namespace {
       return Result;
     }
 
+    QualType TransformAtomicType(TypeLocBuilder &TLB, AtomicTypeLoc TL) {
+      // When building the function parameter for placeholder type deduction
+      // (Replacement is the invented template parameter), dig through _Atomic
+      // around an auto placeholder so deduction matches the non-atomic
+      // argument. The _Atomic wrapper is re-applied by the final substitution
+      // pass, which uses a concrete Replacement and falls through to the
+      // default transform.
+      //
+      // This handles only the simple case where _Atomic wraps auto directly
+      // (e.g. _Atomic(auto)), which is what the C standard currently permits.
+      // If more complex forms such as _Atomic(auto*) are ever allowed, the
+      // correct fix would be to treat _Atomic as a qualifier inside
+      // DeduceTemplateArgumentsByTypeMatch instead.
+      if (isa_and_nonnull<TemplateTypeParmType>(Replacement) &&
+          TL.getValueLoc().getType()->getContainedAutoType())
+        return getDerived().TransformType(TLB, TL.getValueLoc());
+      return inherited::TransformAtomicType(TLB, TL);
+    }
+
     ExprResult TransformLambdaExpr(LambdaExpr *E) {
       // Lambdas never need to be transformed.
       return E;

diff  --git a/clang/test/CodeGen/atomic-auto-type.c 
b/clang/test/CodeGen/atomic-auto-type.c
new file mode 100644
index 0000000000000..0969f22596421
--- /dev/null
+++ b/clang/test/CodeGen/atomic-auto-type.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s > /dev/null
+
+// This is a regression test for handling of __auto_type inside _Atomic.
+// Previously this could lead to an undeduced AutoType escaping into
+// ASTContext::getTypeInfoImpl and causing an assertion failure.
+
+void f(double x) {
+  __auto_type _Atomic xa = x;
+  _Atomic __auto_type ax = x;
+}

diff  --git a/clang/test/Sema/atomic-auto-type.c 
b/clang/test/Sema/atomic-auto-type.c
new file mode 100644
index 0000000000000..ff067662a759e
--- /dev/null
+++ b/clang/test/Sema/atomic-auto-type.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only %s
+// expected-no-diagnostics
+
+int main() {
+  double x = 37;
+
+  __auto_type _Atomic xa = x;
+  _Atomic __auto_type ax = x;
+  
+  _Static_assert(
+      __builtin_types_compatible_p(__typeof(xa), _Atomic double),
+      "incorrect xa type");
+
+  _Static_assert(
+      __builtin_types_compatible_p(__typeof(ax), _Atomic double),
+      "incorrect ax type");
+
+  _Static_assert(
+      __builtin_types_compatible_p(_Atomic double, __typeof(xa)),
+      "incorrect");
+
+  _Static_assert(
+      __builtin_types_compatible_p(_Atomic double, __typeof(ax)),
+      "incorrect");
+  return 0;
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to