[all-commits] [llvm/llvm-project] 4409a8: [clang] Correct handling of lambdas in lambda defa...

Tom Honermann via All-commits all-commits at lists.llvm.org
Tue Oct 4 09:09:10 PDT 2022


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 4409a83c293537e22da046b54e9f69454cdd3dca
      https://github.com/llvm/llvm-project/commit/4409a83c293537e22da046b54e9f69454cdd3dca
  Author: Tom Honermann <tom.honermann at intel.com>
  Date:   2022-10-04 (Tue, 04 Oct 2022)

  Changed paths:
    M clang/include/clang/Sema/Sema.h
    M clang/lib/AST/DeclBase.cpp
    M clang/lib/Sema/SemaTemplateInstantiate.cpp
    M clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    M clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
    A clang/test/CodeGenCXX/mangle-lambdas-cxx14.cpp
    A clang/test/CodeGenCXX/mangle-lambdas-cxx20.cpp
    M clang/test/CodeGenCXX/mangle-lambdas.cpp
    M clang/test/SemaCXX/vartemplate-lambda.cpp
    M clang/test/SemaTemplate/default-arguments.cpp
    M clang/test/SemaTemplate/instantiate-local-class.cpp

  Log Message:
  -----------
  [clang] Correct handling of lambdas in lambda default arguments in dependent contexts.

Previously, a lambda expression in a dependent context with a default argument
containing an immediately invoked lambda expression would produce a closure
class object that, if invoked such that the default argument was used, resulted
in a compiler crash or one of the following assertion failures during code
generation. The failures occurred regardless of whether the lambda expressions
were dependent.

  clang/lib/CodeGen/CGCall.cpp:
  Assertion `(isGenericMethod || Ty->isVariablyModifiedType() || Ty.getNonReferenceType()->isObjCRetainableType() || getContext() .getCanonicalType(Ty.getNonReferenceType()) .getTypePtr() == getContext().getCanonicalType((*Arg)->getType()).getTypePtr()) && "type mismatch in call argument!"' failed.

  clang/lib/AST/Decl.cpp:
  Assertion `!Init->isValueDependent()' failed.

Default arguments in declarations in local context are instantiated along with
their enclosing function or variable template (since such declarations can't
be explicitly specialized). Previously, such instantiations were performed at
the same time that their associated parameters were instantiated. However, that
approach fails in cases like the following in which the context for the inner
lambda is the outer lambda, but construction of the outer lambda is dependent
on the parameters of the inner lambda. This change resolves this dependency by
delyaing instantiation of default arguments in local contexts until after
construction of the enclosing context.
  template <typename T>
  auto f() {
    return [](T = []{ return T{}; }()) { return 0; };
  }

Refactoring included with this change results in the same code now being used
to instantiate default arguments that appear in local context and those that
are only instantiated when used at a call site; previously, such code was
duplicated and out of sync.

Fixes https://github.com/llvm/llvm-project/issues/49178

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D133500




More information about the All-commits mailing list