@@ -858,6 +858,8 @@ namespace {
858
858
TypeChecker &TC;
859
859
DeclContext *DC;
860
860
861
+ Expr *ParentExpr;
862
+
861
863
// / A stack of expressions being walked, used to determine where to
862
864
// / insert RebindSelfInConstructorExpr nodes.
863
865
llvm::SmallVector<Expr *, 8 > ExprStack;
@@ -886,7 +888,8 @@ namespace {
886
888
void resolveKeyPathExpr (KeyPathExpr *KPE);
887
889
888
890
public:
889
- PreCheckExpression (TypeChecker &tc, DeclContext *dc) : TC(tc), DC(dc) { }
891
+ PreCheckExpression (TypeChecker &tc, DeclContext *dc, Expr *parent)
892
+ : TC(tc), DC(dc), ParentExpr(parent) {}
890
893
891
894
bool walkToClosureExprPre (ClosureExpr *expr);
892
895
@@ -947,6 +950,43 @@ namespace {
947
950
return finish (true , expr);
948
951
}
949
952
953
+ // Let's try to figure out if `InOutExpr` is out of place early
954
+ // otherwise there is a risk of producing solutions which can't
955
+ // be later applied to AST and would result in the crash in some
956
+ // cases. Such expressions are only allowed in argument positions
957
+ // of function/operator calls.
958
+ if (isa<InOutExpr>(expr)) {
959
+ // If this is an implicit `inout` expression we assume that
960
+ // compiler knowns what it's doing.
961
+ if (expr->isImplicit ())
962
+ return finish (true , expr);
963
+
964
+ if (TC.isExprBeingDiagnosed (ParentExpr) ||
965
+ TC.isExprBeingDiagnosed (expr))
966
+ return finish (true , expr);
967
+
968
+ auto parents = ParentExpr->getParentMap ();
969
+
970
+ auto result = parents.find (expr);
971
+ if (result != parents.end ()) {
972
+ auto *parent = result->getSecond ();
973
+
974
+ if (isa<SequenceExpr>(parent))
975
+ return finish (true , expr);
976
+
977
+ if (isa<TupleExpr>(parent) || isa<ParenExpr>(parent)) {
978
+ auto call = parents.find (parent);
979
+ if (call != parents.end () &&
980
+ (isa<ApplyExpr>(call->getSecond ()) ||
981
+ isa<UnresolvedMemberExpr>(call->getSecond ())))
982
+ return finish (true , expr);
983
+ }
984
+ }
985
+
986
+ TC.diagnose (expr->getStartLoc (), diag::extraneous_address_of);
987
+ return finish (false , nullptr );
988
+ }
989
+
950
990
return finish (true , expr);
951
991
}
952
992
@@ -1683,7 +1723,7 @@ CleanupIllFormedExpressionRAII::~CleanupIllFormedExpressionRAII() {
1683
1723
// / Pre-check the expression, validating any types that occur in the
1684
1724
// / expression and folding sequence expressions.
1685
1725
bool TypeChecker::preCheckExpression (Expr *&expr, DeclContext *dc) {
1686
- PreCheckExpression preCheck (*this , dc);
1726
+ PreCheckExpression preCheck (*this , dc, expr );
1687
1727
// Perform the pre-check.
1688
1728
if (auto result = expr->walk (preCheck)) {
1689
1729
expr = result;
0 commit comments