diff options
-rw-r--r-- | include/flang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | include/flang/Sema/Sema.h | 16 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExecStmt.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 99 | ||||
-rw-r--r-- | test/Sema/type.f95 | 8 |
6 files changed, 28 insertions, 111 deletions
diff --git a/include/flang/Basic/DiagnosticSemaKinds.td b/include/flang/Basic/DiagnosticSemaKinds.td index 1cde03b208..2ded6c4136 100644 --- a/include/flang/Basic/DiagnosticSemaKinds.td +++ b/include/flang/Basic/DiagnosticSemaKinds.td @@ -51,8 +51,8 @@ def err_typecheck_passing_incompatible_named_args : Error< "passing %0 to parameter '%1' of incompatible type %2 (or parameter '%3' of type %4)">; def note_typecheck_passing_argument_to_param_here : Note< "passing argument to parameter %0 here">; -def note_typecheck_passing_argument_to_field_here : Note< - "passing argument to field %0 declared here">; +def note_typecheck_initializing_member_here : Note< + "initializing member %0 declared here">; def err_typecheck_arith_invalid_operands : Error< "invalid operands to an arithmetic binary expression (%0 and %1)">; diff --git a/include/flang/Sema/Sema.h b/include/flang/Sema/Sema.h index 0053f29d71..1d6c40929d 100644 --- a/include/flang/Sema/Sema.h +++ b/include/flang/Sema/Sema.h @@ -565,14 +565,20 @@ public: }; private: Type ActTy; + const Decl *D; public: AssignmentAction(Type Ty) - : ActTy(Ty) {} + : ActTy(Ty), D(nullptr) {} + AssignmentAction(Type Ty, const Decl *d) + : ActTy(Ty), D(d) {} Type getType() const { return ActTy; } + const Decl *getDecl() const { + return D; + } }; /// AssignConvertType - All of the 'assignment' semantic checks return this @@ -892,14 +898,6 @@ public: /// Returns true if the given character length can be applied to a declaration. bool CheckCharacterLengthDeclarationCompability(QualType T, VarDecl *VD); - - - /// Performs assignment typechecking. - ExprResult TypecheckAssignment(QualType LHSType, ExprResult RHS, - SourceLocation Loc = SourceLocation(), - SourceRange LHSRange = SourceRange(), - SourceRange RHSRange = SourceRange()); - /// Returns true if the subscript expression has the /// right amount of dimensions. bool CheckSubscriptExprDimensionCount(SourceLocation Loc, SourceLocation RParenLoc, diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 757b4ec469..97702bbe01 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -957,9 +957,9 @@ StmtResult Sema::ActOnAssignmentStmt(ASTContext &C, SourceLocation Loc, if(LHS.get()->getType().isNull() || RHS.get()->getType().isNull()) return StmtError(); - RHS = TypecheckAssignment(LHS.get()->getType(), RHS, - Loc, LHS.get()->getSourceRange(), - RHS.get()->getSourceRange()); + RHS = CheckAndApplyAssignmentConstraints(Loc, LHS.get()->getType(), + RHS.get(), AssignmentAction::Assigning, + LHS.get()); if(RHS.isInvalid()) return StmtError(); auto Result = AssignmentStmt::Create(C, Loc, LHS.take(), RHS.take(), StmtLabel); diff --git a/lib/Sema/SemaExecStmt.cpp b/lib/Sema/SemaExecStmt.cpp index ac31e1c92e..168aa68d23 100644 --- a/lib/Sema/SemaExecStmt.cpp +++ b/lib/Sema/SemaExecStmt.cpp @@ -177,15 +177,15 @@ StmtResult Sema::ActOnDoStmt(ASTContext &C, SourceLocation Loc, SourceLocation E auto DoVarType = DoVar->getType(); if(E1.isUsable()) { if(CheckScalarNumericExpression(E1.get())) - E1 = TypecheckAssignment(DoVarType, E1); + E1 = CheckAndApplyAssignmentConstraints(Loc, DoVarType, E1.get(), AssignmentAction::Converting); } else AddToBody = false; if(E2.isUsable()) { if(CheckScalarNumericExpression(E2.get())) - E2 = TypecheckAssignment(DoVarType, E2); + E2 = CheckAndApplyAssignmentConstraints(Loc, DoVarType, E2.get(), AssignmentAction::Converting); } else AddToBody = false; if(E3.isUsable()) { if(CheckScalarNumericExpression(E3.get())) - E3 = TypecheckAssignment(DoVarType, E3); + E3 = CheckAndApplyAssignmentConstraints(Loc, DoVarType, E3.get(), AssignmentAction::Converting); } } else AddToBody = false; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 32ef2d1442..e2e2021067 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -206,52 +206,6 @@ static TypecheckAction TypecheckAssignment(ASTContext &Context, return Result; } -template<typename T> -static ExprResult TypecheckAssignment(Sema &S, QualType LHSType, ExprResult RHS, - T& Handler, SourceLocation Loc, - SourceRange LHSRange, SourceRange RHSRange) { - auto RHSType = RHS.get()->getType(); - if(LHSType->isArrayType()) { - auto LHSElementType = LHSType->asArrayType()->getElementType(); - if(RHSType->isArrayType()) { - auto RHSElementType = RHSType->asArrayType()->getElementType(); - - // Check the array compabilities - if(!S.CheckArrayDimensionsCompability(LHSType->asArrayType(), - RHSType->asArrayType(), - Loc, - LHSRange, - RHSRange)) - return S.ExprError(); - - // cast an array to appropriate type. - auto Action = TypecheckAssignment(S.getContext(), LHSElementType, RHSElementType); - if(Action == NoAction) - return RHS; - else if(Action == ImplicitCastAction) - return ImplicitCastExpr::Create(S.getContext(), RHS.get()->getLocation(), - S.getContext().getArrayType(LHSElementType, - RHSType->asArrayType()->getDimensions()), - RHS.take()); - - Handler.IncompatibleTypes(Loc, LHSElementType, RHSElementType); - return S.ExprError(); - } - else - LHSType = LHSElementType; // fallthrough - } - - auto Action = TypecheckAssignment(S.getContext(), LHSType, RHSType); - if(Action == NoAction) - return RHS; - else if(Action == ImplicitCastAction) - return ImplicitCastExpr::Create(S.getContext(), RHS.get()->getLocation(), - LHSType, RHS.take()); - - Handler.IncompatibleTypes(Loc, LHSType, RHSType); - return S.ExprError(); -}; - bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, @@ -289,8 +243,13 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, Reporter << DstType << SrcType; else if(Action.getType() == AssignmentAction::Returning) Reporter << SrcType << DstType; - break; + } { + if(auto Field = dyn_cast_or_null<FieldDecl>(Action.getDecl())) { + Diags.Report(Field->getLocation(), diag::note_typecheck_initializing_member_here) + << Field->getIdentifier(); + } } + break; case IncompatibleDimensions: break; } @@ -346,30 +305,6 @@ CheckAndApplyAssignmentConstraints(SourceLocation Loc, QualType LHSType, return ExprError(); } -ExprResult Sema::TypecheckAssignment(QualType LHSType, ExprResult RHS, - SourceLocation Loc, SourceRange LHSRange, - SourceRange RHSRange) { - struct Reporter { - DiagnosticsEngine &Diags; - SourceRange LHSRange, RHSRange; - Reporter(DiagnosticsEngine &Diag, - SourceRange LHS, SourceRange RHS) - : Diags(Diag), LHSRange(LHS), RHSRange(RHS) {} - - void IncompatibleTypes(SourceLocation Loc, QualType LHSType, QualType RHSType) { - auto Reporter = Diags.Report(Loc, diag::err_typecheck_assign_incompatible) - << LHSType << RHSType; - if(LHSRange.isValid()) - Reporter << LHSRange; - if(RHSRange.isValid()) - Reporter << RHSRange; - } - }; - Reporter Handler(Diags, LHSRange, RHSRange); - return ::flang::TypecheckAssignment(*this, LHSType, RHS, Handler, Loc, LHSRange, RHSRange); -} - - ExprResult Sema::ActOnComplexConstantExpr(ASTContext &C, SourceLocation Loc, SourceLocation MaxLoc, ExprResult RealPart, ExprResult ImPart) { @@ -898,22 +833,6 @@ ExprResult Sema::ActOnIntrinsicFunctionCallExpr(ASTContext &C, SourceLocation Lo ExprResult Sema::ActOnTypeConstructorExpr(ASTContext &C, SourceLocation Loc, SourceLocation LParenLoc, SourceLocation RParenLoc, RecordDecl *Record, ArrayRef<Expr*> Arguments) { - struct TypecheckReporter { - DiagnosticsEngine &Diags; - FieldDecl *Field; - Expr *Arg; - - TypecheckReporter(DiagnosticsEngine &Diag, FieldDecl *F, Expr *E) - : Diags(Diag), Field(F), Arg(E) {} - - void IncompatibleTypes(SourceLocation Loc, QualType FieldType, QualType ArgType) { - Diags.Report(Loc, diag::err_typecheck_passing_incompatible) - << ArgType << FieldType << Arg->getSourceRange(); - Diags.Report(Field->getLocation(), diag::note_typecheck_passing_argument_to_field_here) - << Field->getIdentifier(); - } - }; - SmallVector<Expr*, 8> Args; auto ReturnType = C.getRecordType(Record); auto Fields = cast<RecordType>(ReturnType.getTypePtr())->getElements(); @@ -928,9 +847,9 @@ ExprResult Sema::ActOnTypeConstructorExpr(ASTContext &C, SourceLocation Loc, break; } auto Arg = Arguments[ArgumentId]; - TypecheckReporter Handler(Diags, Fields[I], Arg); - auto E = ::flang::TypecheckAssignment(*this, Fields[I]->getType(), Arg, Handler, - Arg->getLocation(), SourceRange(), Arg->getSourceRange()); + auto E = CheckAndApplyAssignmentConstraints(Arg->getLocation(), Fields[I]->getType(), + Arg, AssignmentAction(AssignmentAction::Initializing, + Fields[I])); if(E.isUsable()) Args.push_back(E.get()); } diff --git a/test/Sema/type.f95 b/test/Sema/type.f95 index d563a056f9..f267c0109a 100644 --- a/test/Sema/type.f95 +++ b/test/Sema/type.f95 @@ -16,8 +16,8 @@ PROGRAM typetest INTEGER Bar ! expected-note {{previous definition is here}} TYPE Point - REAL X, Y ! expected-note {{passing argument to field 'x' declared here}} - END TYPE Point ! expected-note@-1 {{passing argument to field 'y' declared here}} + REAL X, Y ! expected-note {{initializing member 'x' declared here}} + END TYPE Point ! expected-note@-1 {{initializing member 'y' declared here}} type Triangle type(Point) vertices(3) @@ -63,8 +63,8 @@ PROGRAM typetest i = p ! expected-error {{assigning to 'integer' from incompatible type 'type point'}} tri = p ! expected-error {{assigning to 'type triangle' from incompatible type 'type point'}} - p = Point(.true., p) ! expected-error {{passing 'logical' to parameter of incompatible type 'real'}} - continue ! expected-error@-1 {{passing 'type point' to parameter of incompatible type 'real'}} + p = Point(.true., p) ! expected-error {{initializing 'real' with an expression of incompatible type 'logical'}} + continue ! expected-error@-1 {{initializing 'real' with an expression of incompatible type 'type point'}} p = Point(0.0) ! expected-error {{too few arguments to type constructor, expected 2, have 1}} p = Point(0.0, 1.0, 2.0) ! expected-error {{too many arguments to type constructor, expected 2, have 3}} p = Point() ! expected-error {{too few arguments to type constructor, expected 2, have 0}} |