[llvm-branch-commits] [clang] 825f80e - [Sema] Introduce function reference conversion, NFC
Aaron Puchert via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Nov 22 11:56:39 PST 2020
Author: Aaron Puchert
Date: 2020-11-22T20:51:57+01:00
New Revision: 825f80e111f2815a009084f65267be3b5bf0897a
URL: https://github.com/llvm/llvm-project/commit/825f80e111f2815a009084f65267be3b5bf0897a
DIFF: https://github.com/llvm/llvm-project/commit/825f80e111f2815a009084f65267be3b5bf0897a.diff
LOG: [Sema] Introduce function reference conversion, NFC
Technically 'noexcept' isn't a qualifier, so this should be a separate conversion.
Also make the test a pure frontend test.
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D67112
Added:
clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4-ast.cpp
Modified:
clang/include/clang/AST/OperationKinds.def
clang/include/clang/Sema/Initialization.h
clang/lib/Sema/SemaInit.cpp
Removed:
clang/test/CodeGenCXX/implicit-function-conversion.cpp
################################################################################
diff --git a/clang/include/clang/AST/OperationKinds.def b/clang/include/clang/AST/OperationKinds.def
index 6daab1ffcb0a..7c82ab6e57ef 100644
--- a/clang/include/clang/AST/OperationKinds.def
+++ b/clang/include/clang/AST/OperationKinds.def
@@ -77,9 +77,10 @@ CAST_OPERATION(LValueToRValueBitCast)
CAST_OPERATION(LValueToRValue)
/// CK_NoOp - A conversion which does not affect the type other than
-/// (possibly) adding qualifiers.
+/// (possibly) adding qualifiers or removing noexcept.
/// int -> int
/// char** -> const char * const *
+/// void () noexcept -> void ()
CAST_OPERATION(NoOp)
/// CK_BaseToDerived - A conversion from a C++ class pointer/reference
diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h
index 6976e7c95c8b..2245c1505001 100644
--- a/clang/include/clang/Sema/Initialization.h
+++ b/clang/include/clang/Sema/Initialization.h
@@ -840,6 +840,9 @@ class InitializationSequence {
/// Perform a qualification conversion, producing an lvalue.
SK_QualificationConversionLValue,
+ /// Perform a function reference conversion, see [dcl.init.ref]p4.
+ SK_FunctionReferenceConversion,
+
/// Perform a conversion adding _Atomic to a type.
SK_AtomicConversion,
@@ -1288,6 +1291,10 @@ class InitializationSequence {
void AddQualificationConversionStep(QualType Ty,
ExprValueKind Category);
+ /// Add a new step that performs a function reference conversion to the
+ /// given type.
+ void AddFunctionReferenceConversionStep(QualType Ty);
+
/// Add a new step that performs conversion from non-atomic to atomic
/// type.
void AddAtomicConversionStep(QualType Ty);
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 5131ce446d04..6d2e6094e79c 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3442,6 +3442,7 @@ void InitializationSequence::Step::Destroy() {
case SK_QualificationConversionRValue:
case SK_QualificationConversionXValue:
case SK_QualificationConversionLValue:
+ case SK_FunctionReferenceConversion:
case SK_AtomicConversion:
case SK_ListInitialization:
case SK_UnwrapInitList:
@@ -3620,6 +3621,13 @@ void InitializationSequence::AddQualificationConversionStep(QualType Ty,
Steps.push_back(S);
}
+void InitializationSequence::AddFunctionReferenceConversionStep(QualType Ty) {
+ Step S;
+ S.Kind = SK_FunctionReferenceConversion;
+ S.Type = Ty;
+ Steps.push_back(S);
+}
+
void InitializationSequence::AddAtomicConversionStep(QualType Ty) {
Step S;
S.Kind = SK_AtomicConversion;
@@ -4653,7 +4661,7 @@ static OverloadingResult TryRefInitWithConversionFunction(
else if (RefConv & Sema::ReferenceConversions::ObjC)
Sequence.AddObjCObjectConversionStep(cv1T1);
else if (RefConv & Sema::ReferenceConversions::Function)
- Sequence.AddQualificationConversionStep(cv1T1, VK);
+ Sequence.AddFunctionReferenceConversionStep(cv1T1);
else if (RefConv & Sema::ReferenceConversions::Qualification) {
if (!S.Context.hasSameType(cv1T4, cv1T1))
Sequence.AddQualificationConversionStep(cv1T1, VK);
@@ -4755,12 +4763,12 @@ static void TryReferenceInitializationCore(Sema &S,
Sequence.AddDerivedToBaseCastStep(cv1T1, VK_LValue);
else
Sequence.AddObjCObjectConversionStep(cv1T1);
- } else if (RefConv & (Sema::ReferenceConversions::Qualification |
- Sema::ReferenceConversions::Function)) {
+ } else if (RefConv & Sema::ReferenceConversions::Qualification) {
// Perform a (possibly multi-level) qualification conversion.
- // FIXME: Should we use a
diff erent step kind for function conversions?
Sequence.AddQualificationConversionStep(cv1T1,
Initializer->getValueKind());
+ } else if (RefConv & Sema::ReferenceConversions::Function) {
+ Sequence.AddFunctionReferenceConversionStep(cv1T1);
}
// We only create a temporary here when binding a reference to a
@@ -8038,6 +8046,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
case SK_QualificationConversionLValue:
case SK_QualificationConversionXValue:
case SK_QualificationConversionRValue:
+ case SK_FunctionReferenceConversion:
case SK_AtomicConversion:
case SK_ConversionSequence:
case SK_ConversionSequenceNoNarrowing:
@@ -8303,6 +8312,13 @@ ExprResult InitializationSequence::Perform(Sema &S,
break;
}
+ case SK_FunctionReferenceConversion:
+ assert(CurInit.get()->isLValue() &&
+ "function reference should be lvalue");
+ CurInit =
+ S.ImpCastExprToType(CurInit.get(), Step->Type, CK_NoOp, VK_LValue);
+ break;
+
case SK_AtomicConversion: {
assert(CurInit.get()->isRValue() && "cannot convert glvalue to atomic");
CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
@@ -9563,6 +9579,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
OS << "qualification conversion (lvalue)";
break;
+ case SK_FunctionReferenceConversion:
+ OS << "function reference conversion";
+ break;
+
case SK_AtomicConversion:
OS << "non-atomic-to-atomic conversion";
break;
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4-ast.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4-ast.cpp
new file mode 100644
index 000000000000..4fc0a05ae1ec
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p4-ast.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++17 -ast-dump %s | FileCheck %s
+
+void f() noexcept;
+
+// CHECK: VarDecl {{.*}} ref 'void (&)()' cinit
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void ()':'void ()' lvalue <NoOp>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'void () noexcept' lvalue Function {{.*}} 'f' 'void () noexcept'
+void (&ref)() = f;
+
+struct X {
+ typedef void (&ref)() noexcept;
+ operator ref();
+} x;
+
+// CHECK: VarDecl {{.*}} xp 'void (&)()' cinit
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void ()':'void ()' lvalue <NoOp>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void () noexcept':'void () noexcept' lvalue <UserDefinedConversion>
+void (&xp)() = x;
diff --git a/clang/test/CodeGenCXX/implicit-function-conversion.cpp b/clang/test/CodeGenCXX/implicit-function-conversion.cpp
deleted file mode 100644
index bc4b2bc8d15c..000000000000
--- a/clang/test/CodeGenCXX/implicit-function-conversion.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-unknown-linux -std=c++17 | FileCheck %s
-
-double a(double) noexcept;
-int b(double (&)(double));
-
-// CHECK: call i32 @_Z1bRFddE(double (double)* nonnull @_Z1ad)
-int c = b(a);
More information about the llvm-branch-commits
mailing list