llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Kaushal1042 (KaushalMorankar)

<details>
<summary>Changes</summary>

```markdown
Fixes #<!-- -->166957

This PR fixes an inconsistency where `getTypeSourceInfo()-&gt;getType()` and 
`getType()` return different `AutoType` instances with different 
`isDependentType()` values for constrained auto variables in dependent contexts.

Solution

The fix adds logic in ActOnVariableDeclarator 
(clang/lib/Sema/SemaDecl.cpp:7700-7719) to check if a constrained AutoType is 
being created, and ensures its dependency status matches the declaration 
context:
- In dependent contexts (e.g., templates): undeduced constrained autos are 
marked as dependent
- In non-dependent contexts: they are not marked as dependent

The fix reconstructs the AutoType with the correct dependency flag and updates 
the TypeSourceInfo to maintain consistency between both type retrieval methods.

Testing
Added comprehensive test coverage in 
clang/test/SemaCXX/constrained-auto-type-consistency.cpp which includes:
- Constrained auto in abbreviated function templates (dependent context)
- Constrained auto at namespace scope (non-dependent context) etc.

All tests pass with expected-no-diagnostics, confirming the fix resolves the 
inconsistency without introducing new issues.

Files Changed
- clang/lib/Sema/SemaDecl.cpp: Added logic to ensure AutoType dependency 
consistency
- clang/test/SemaCXX/constrained-auto-type-consistency.cpp: New test file (92 
lines)


---
Full diff: https://github.com/llvm/llvm-project/pull/167100.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaDecl.cpp (+20) 
- (added) clang/test/SemaCXX/constrained-auto-type-consistency.cpp (+92) 


``````````diff
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 086dd8ba1c670..99877615c50bf 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7697,6 +7697,26 @@ NamedDecl *Sema::ActOnVariableDeclarator(
     LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists,
     bool &AddToScope, ArrayRef<BindingDecl *> Bindings) {
   QualType R = TInfo->getType();
+  
+  if (const AutoType *AT = R->getContainedAutoType()) {
+    if (AT->isConstrained()) {
+      bool IsInDependentContext = DC->isDependentContext();
+      bool ShouldBeDependent = IsInDependentContext && !AT->isDeduced();
+
+      if (ShouldBeDependent != AT->isDependentType()) {
+        QualType CanonAuto = Context.getAutoType(
+            AT->isDeduced() ? AT->getDeducedType() : QualType(),
+            AT->getKeyword(),
+            ShouldBeDependent,
+            false,
+            AT->getTypeConstraintConcept(),
+            AT->getTypeConstraintArguments());
+
+        R = Context.getQualifiedType(CanonAuto, R.getQualifiers());
+        TInfo = Context.getTrivialTypeSourceInfo(R, D.getBeginLoc());
+      }
+    }
+  }
   DeclarationName Name = GetNameForDeclarator(D).getName();
 
   IdentifierInfo *II = Name.getAsIdentifierInfo();
diff --git a/clang/test/SemaCXX/constrained-auto-type-consistency.cpp 
b/clang/test/SemaCXX/constrained-auto-type-consistency.cpp
new file mode 100644
index 0000000000000..7f6cec1604151
--- /dev/null
+++ b/clang/test/SemaCXX/constrained-auto-type-consistency.cpp
@@ -0,0 +1,92 @@
+// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
+
+namespace std {
+  template<typename T>
+  concept integral = __is_integral(T);
+
+  template<typename T>
+  concept floating_point = __is_floating_point(T);
+}
+
+// Constrained auto in abbreviated function template
+void find(auto value) {
+  std::integral auto var = value;
+}
+
+// Constrained auto at namespace scope (non-dependent context)
+// Should be deduced immediately
+std::integral auto globalVar = 42;
+
+// Multiple constrained autos in template function
+template<typename T>
+void multipleConstrainedAutos(T value) {
+  std::integral auto x = 10;
+  std::floating_point auto y = 3.14;
+  std::integral auto z = value; // dependent on T
+}
+
+// Constrained auto with qualifiers
+void testQualifiers(auto value) {
+  const std::integral auto cv1 = value;
+  std::integral auto const cv2 = value;
+}
+
+// Nested constrained auto
+void testNested(auto outer) {
+  auto lambda = [](auto inner) {
+    std::integral auto nested = inner;
+    return nested;
+  };
+
+  std::integral auto result = lambda(outer);
+}
+
+// Constrained auto with references
+void testReferences(auto value) {
+  std::integral auto& ref = value;
+  const std::integral auto& cref = value;
+}
+
+// Regular unconstrained auto (should not be affected by the fix)
+void testUnconstrainedAuto(auto value) {
+  auto regular = value;
+  decltype(auto) decl_auto = (value);
+}
+
+// Constrained auto in class template member
+template<typename T>
+struct Container {
+  void process(auto item) {
+    std::integral auto local = item;
+  }
+};
+
+// Constrained auto deduction from function call
+std::integral auto getInteger() { return 42; }
+
+void testFunctionReturn(auto param) {
+  std::integral auto fromFunc = getInteger();
+  std::integral auto fromParam = param;
+}
+
+// Ensure the fix doesn't break normal non-template constrained auto
+void normalFunction() {
+  std::integral auto x = 100;
+  // This should be immediately deduced to int, not dependent
+}
+
+// Instantiate templates to verify no crashes
+void instantiateAll() {
+  find(42);
+  multipleConstrainedAutos(5);
+  testQualifiers(7);
+  testNested(8);
+  int val = 10;
+  testReferences(val);
+  testUnconstrainedAuto(11);
+  Container<int> c;
+  c.process(12);
+  testFunctionReturn(13);
+  normalFunction();
+}

``````````

</details>


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

Reply via email to