diff --git a/lib/Sema/LegalConstExprVerifier.cpp b/lib/Sema/LegalConstExprVerifier.cpp index ddf7be87368bd..234e4435b3094 100644 --- a/lib/Sema/LegalConstExprVerifier.cpp +++ b/lib/Sema/LegalConstExprVerifier.cpp @@ -216,9 +216,18 @@ checkSupportedWithSectionAttribute(const Expr *expr, if (isa(expr)) return std::make_pair(expr, Closure); - // Function conversions are not allowed in constant expressions - if (isa(expr)) + // Function conversions are allowed if the conversion is to '@convention(c)' + if (auto functionConvExpr = dyn_cast(expr)) { + if (auto targetFnTy = + functionConvExpr->getType()->getAs()) { + if (targetFnTy->getExtInfo().getRepresentation() == + FunctionTypeRepresentation::CFunctionPointer) { + expressionsToCheck.push_back(functionConvExpr->getSubExpr()); + continue; + } + } return std::make_pair(expr, Default); + } // Direct references to non-generic functions are allowed if (const DeclRefExpr *declRef = dyn_cast(expr)) { diff --git a/test/ConstValues/SectionSyntactic.swift b/test/ConstValues/SectionSyntactic.swift index 0ff8b3e651aee..6a33f589e7f1e 100644 --- a/test/ConstValues/SectionSyntactic.swift +++ b/test/ConstValues/SectionSyntactic.swift @@ -46,6 +46,8 @@ func bar(x: Int) -> String { return "test" } // function references @section("mysection") let funcRef1 = foo // ok @section("mysection") let funcRef2 = bar // ok +@section("mysection") let funcRef3: ()->Int = foo // ok +@section("mysection") let funcRef4: @convention(c) ()->Int = foo // ok // invalid function references (should be rejected) @section("mysection") let invalidFuncRef1 = foo()