summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarphaman <arphaman@gmail.com>2013-09-13 12:55:35 +0100
committerarphaman <arphaman@gmail.com>2013-09-13 12:55:35 +0100
commitb91022b3f88ebedd2e405857862b11f0d26ad489 (patch)
tree81f7de6e65b57af43e91ad62ad2ee226c9202a3d
parent43e78c02ca0fbe7219efb962b2fd8dd03dda318e (diff)
downloadflang-b91022b3f88ebedd2e405857862b11f0d26ad489.tar.gz
improved sema for data stmt
-rw-r--r--include/flang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaDataStmt.cpp15
-rw-r--r--test/Sema/data.f955
3 files changed, 21 insertions, 2 deletions
diff --git a/include/flang/Basic/DiagnosticSemaKinds.td b/include/flang/Basic/DiagnosticSemaKinds.td
index 553332441d..c00fc612dc 100644
--- a/include/flang/Basic/DiagnosticSemaKinds.td
+++ b/include/flang/Basic/DiagnosticSemaKinds.td
@@ -319,6 +319,9 @@ def err_data_stmt_not_enough_values : Error<
"not enough values in a 'data' statement">;
def err_data_stmt_invalid_item : Error<
"invalid item for a 'data' statement">;
+def err_data_stmt_invalid_var : Error<
+ "%select{parameter constant|function argument|function result variable}0 "
+ "can't be initialized by a 'data' statement">;
def err_multiple_default_case_stmt : Error<
"multiple default cases in one select case construct">;
diff --git a/lib/Sema/SemaDataStmt.cpp b/lib/Sema/SemaDataStmt.cpp
index 88d4693c26..09e9872adf 100644
--- a/lib/Sema/SemaDataStmt.cpp
+++ b/lib/Sema/SemaDataStmt.cpp
@@ -98,6 +98,7 @@ class DataStmtEngine : public ExprVisitor<DataStmtEngine> {
ExprResult getAndCheckValue(QualType LHSType, const Expr *LHS);
ExprResult getAndCheckAnyValue(QualType LHSType, const Expr *LHS);
+ void getValueOnError();
public:
DataStmtEngine(DataValueIterator &Vals, flang::Sema &S,
DiagnosticsEngine &Diag, SourceLocation Loc)
@@ -140,12 +141,17 @@ bool DataStmtEngine::HasValues(const Expr *Where) {
void DataStmtEngine::VisitExpr(Expr *E) {
Diags.Report(E->getLocation(), diag::err_data_stmt_invalid_item)
<< E->getSourceRange();
+ getValueOnError();
}
bool DataStmtEngine::CheckVar(VarExpr *E) {
auto VD = E->getVarDecl();
- if(VD->isArgument() || VD->isParameter()) {
- VisitExpr(E);
+ if(VD->isArgument() || VD->isParameter() ||
+ VD->isFunctionResult()) {
+ Diags.Report(E->getLocation(), diag::err_data_stmt_invalid_var)
+ << (VD->isParameter()? 0 : VD->isArgument()? 1 : 2)
+ << VD->getIdentifier() << E->getSourceRange();
+ getValueOnError();
return true;
}
if(VD->isUnusedSymbol())
@@ -175,6 +181,11 @@ ExprResult DataStmtEngine::getAndCheckAnyValue(QualType LHSType, const Expr *LHS
return Val;
}
+void DataStmtEngine::getValueOnError() {
+ if(!Values.isEmpty())
+ Values.advance();
+}
+
void DataStmtEngine::VisitVarExpr(VarExpr *E) {
if(CheckVar(E))
return;
diff --git a/test/Sema/data.f95 b/test/Sema/data.f95
index d0dcd496bc..cb42cf2f94 100644
--- a/test/Sema/data.f95
+++ b/test/Sema/data.f95
@@ -138,3 +138,8 @@ subroutine sub5
! FIXME: TODO: data (pArr2(i)%x, pArr2(i)%y, i = 2,3) / 1, 2, 3, 4 /
end
+
+integer function func(i)
+ data i / 0 / ! expected-error {{function argument can't be initialized by a 'data' statement}}
+ data func / 12 / ! expected-error {{function result variable can't be initialized by a 'data' statement}}
+end