@@ -852,6 +852,8 @@ namespace {
852
852
TypeChecker &TC;
853
853
DeclContext *DC;
854
854
855
+ Expr *ParentExpr;
856
+
855
857
// / A stack of expressions being walked, used to determine where to
856
858
// / insert RebindSelfInConstructorExpr nodes.
857
859
llvm::SmallVector<Expr *, 8 > ExprStack;
@@ -880,7 +882,8 @@ namespace {
880
882
void resolveKeyPathExpr (KeyPathExpr *KPE);
881
883
882
884
public:
883
- PreCheckExpression (TypeChecker &tc, DeclContext *dc) : TC(tc), DC(dc) { }
885
+ PreCheckExpression (TypeChecker &tc, DeclContext *dc, Expr *parent)
886
+ : TC(tc), DC(dc), ParentExpr(parent) {}
884
887
885
888
bool walkToClosureExprPre (ClosureExpr *expr);
886
889
@@ -941,6 +944,43 @@ namespace {
941
944
return finish (true , expr);
942
945
}
943
946
947
+ // Let's try to figure out if `InOutExpr` is out of place early
948
+ // otherwise there is a risk of producing solutions which can't
949
+ // be later applied to AST and would result in the crash in some
950
+ // cases. Such expressions are only allowed in argument positions
951
+ // of function/operator calls.
952
+ if (isa<InOutExpr>(expr)) {
953
+ // If this is an implicit `inout` expression we assume that
954
+ // compiler knowns what it's doing.
955
+ if (expr->isImplicit ())
956
+ return finish (true , expr);
957
+
958
+ if (TC.isExprBeingDiagnosed (ParentExpr) ||
959
+ TC.isExprBeingDiagnosed (expr))
960
+ return finish (true , expr);
961
+
962
+ auto parents = ParentExpr->getParentMap ();
963
+
964
+ auto result = parents.find (expr);
965
+ if (result != parents.end ()) {
966
+ auto *parent = result->getSecond ();
967
+
968
+ if (isa<SequenceExpr>(parent))
969
+ return finish (true , expr);
970
+
971
+ if (isa<TupleExpr>(parent) || isa<ParenExpr>(parent)) {
972
+ auto call = parents.find (parent);
973
+ if (call != parents.end () &&
974
+ (isa<ApplyExpr>(call->getSecond ()) ||
975
+ isa<UnresolvedMemberExpr>(call->getSecond ())))
976
+ return finish (true , expr);
977
+ }
978
+ }
979
+
980
+ TC.diagnose (expr->getStartLoc (), diag::extraneous_address_of);
981
+ return finish (false , nullptr );
982
+ }
983
+
944
984
return finish (true , expr);
945
985
}
946
986
@@ -1699,7 +1739,7 @@ CleanupIllFormedExpressionRAII::~CleanupIllFormedExpressionRAII() {
1699
1739
// / Pre-check the expression, validating any types that occur in the
1700
1740
// / expression and folding sequence expressions.
1701
1741
bool TypeChecker::preCheckExpression (Expr *&expr, DeclContext *dc) {
1702
- PreCheckExpression preCheck (*this , dc);
1742
+ PreCheckExpression preCheck (*this , dc, expr );
1703
1743
// Perform the pre-check.
1704
1744
if (auto result = expr->walk (preCheck)) {
1705
1745
expr = result;
0 commit comments