summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/flang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--include/flang/Sema/Sema.h16
-rw-r--r--lib/Sema/Sema.cpp6
-rw-r--r--lib/Sema/SemaExecStmt.cpp6
-rw-r--r--lib/Sema/SemaExpr.cpp99
-rw-r--r--test/Sema/type.f958
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}}