Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions lib/Sema/LegalConstExprVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,18 @@ checkSupportedWithSectionAttribute(const Expr *expr,
if (isa<AbstractClosureExpr>(expr))
return std::make_pair(expr, Closure);

// Function conversions are not allowed in constant expressions
if (isa<FunctionConversionExpr>(expr))
// Function conversions are allowed if the conversion is to '@convention(c)'
if (auto functionConvExpr = dyn_cast<FunctionConversionExpr>(expr)) {
if (auto targetFnTy =
functionConvExpr->getType()->getAs<AnyFunctionType>()) {
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<DeclRefExpr>(expr)) {
Expand Down
2 changes: 2 additions & 0 deletions test/ConstValues/SectionSyntactic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down