[clang] [Sema] Fast-path simple plain auto deduction in DeduceAutoType (PR #188196)

Matheus Izvekov via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 22 09:51:40 PDT 2026


================
@@ -5253,7 +5268,56 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result,
 
     DeducedType = getDecltypeForExpr(Init);
     assert(!DeducedType.isNull());
-  } else {
+  } else if (CanTryFastPath) {
+    // Fast-path a subset of `auto` deduction for non-init-list cases in
+    // non-ObjC and non-OpenCL language modes. For these cases, the deduced
+    // type can be computed directly from the initializer type by removing
+    // references, applying array/function decay, and dropping top-level
+    // cv-qualifiers. For single-level `auto*` declarators, the deduced type
+    // is the pointee type of the processed initializer type.
+
+    QualType DeclaredTy = Type.getType();
+    bool IsPlainOrTopLevelCvAuto = Context.hasSameType(
+        DeclaredTy.getLocalUnqualifiedType(), Context.getAutoDeductType());
+    bool IsSimpleAutoStar =
+        DeclaredTy->isPointerType() &&
+        Context.hasSameType(
+            DeclaredTy->getPointeeType().getLocalUnqualifiedType(),
+            Context.getAutoDeductType()) &&
+        !DeclaredTy->getPointeeType().getLocalQualifiers().hasCVRQualifiers();
+
+    QualType ProcessedInitTy = Init->getType().getNonReferenceType();
+    if (ProcessedInitTy->isArrayType() || ProcessedInitTy->isFunctionType())
+      ProcessedInitTy = Context.getDecayedType(ProcessedInitTy);
+
+    ProcessedInitTy = ProcessedInitTy.getUnqualifiedType();
+    bool CanUsePointerFastPath =
+        IsSimpleAutoStar && ProcessedInitTy->isPointerType();
+
+    if (IsPlainOrTopLevelCvAuto) {
+      DeducedType = ProcessedInitTy;
+      FastPathUsed = true;
+    } else if (CanUsePointerFastPath) {
+      DeducedType = ProcessedInitTy->getPointeeType();
+      // Normalize qualifiers on array pointee types so the fast path builds the
+      // same deduced type shape as the slow path.
+      Qualifiers DeducedQuals;
+      DeducedType = Context.getUnqualifiedArrayType(DeducedType, DeducedQuals);
+      DeducedType = Context.getQualifiedType(DeducedType, DeducedQuals);
+      FastPathUsed = true;
+    }
+  }
----------------
mizvekov wrote:

What do you think about sticking this in a function returning a QualType like this?
```suggestion
    QualType ProcessedInitTy = Init->getType().getNonReferenceType();
    if (ProcessedInitTy->isArrayType() || ProcessedInitTy->isFunctionType())
      ProcessedInitTy = Context.getDecayedType(ProcessedInitTy);
    ProcessedInitTy = ProcessedInitTy.getUnqualifiedType();

    // Is this plain `auto`?
    if (Context.hasSameType(
        DeclaredTy.getLocalUnqualifiedType(), Context.getAutoDeductType()))
      return ProcessedInitTy; 
    
    // Is this `auto *` and the initializer is a pointer?
    if (!ProcessedInitTy->isPointerType() ||
        !DeclaredTy->isPointerType() ||
        !Context.hasSameType(
            DeclaredTy->getPointeeType().getLocalUnqualifiedType(),
            Context.getAutoDeductType()) &&
        !DeclaredTy->getPointeeType().getLocalQualifiers().hasCVRQualifiers())
        return QualType();
    
    QualType DeducedType = ProcessedInitTy->getPointeeType();
    // Normalize qualifiers on array pointee types so the fast path builds the
    // same deduced type shape as the slow path.
    Qualifiers DeducedQuals;
    DeducedType = Context.getUnqualifiedArrayType(DeducedType, DeducedQuals);
    DeducedType = Context.getQualifiedType(DeducedType, DeducedQuals);
    return DeducedType;
```

Also, I think the last part about normalizing array qualifiers can be simplified by using `Context.getAsArrayType`.

Though it would be better if the slow path didn't rebalance the qualifiers like this, because this can cause top level sugar on the array type to be stripped-off.

https://github.com/llvm/llvm-project/pull/188196


More information about the cfe-commits mailing list