-
Notifications
You must be signed in to change notification settings - Fork 446
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed bug in name resolution; better shadowing tests #349
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -180,6 +180,7 @@ ResolveReferences::ResolveReferences(ReferenceMap* refMap, | |
void ResolveReferences::addToContext(const IR::INamespace* ns) { | ||
LOG1("Adding to context " << dbp(ns)); | ||
BUG_CHECK(context != nullptr, "No resolution context; did not start at P4Program?"); | ||
checkShadowing(ns); | ||
context->push(ns); | ||
} | ||
|
||
|
@@ -213,24 +214,20 @@ void ResolveReferences::resolvePath(const IR::Path* path, bool isType) const { | |
refMap->setDeclaration(path, decl); | ||
} | ||
|
||
void ResolveReferences::checkShadowing(const IR::INamespace*ns) const { | ||
void ResolveReferences::checkShadowing(const IR::INamespace* ns) const { | ||
if (!checkShadow) return; | ||
|
||
auto e = ns->getDeclarations(); | ||
while (e->moveNext()) { | ||
const IR::IDeclaration* decl = e->getCurrent(); | ||
for (auto decl : *ns->getDeclarations()) { | ||
const IR::Node* node = decl->getNode(); | ||
auto prev = context->resolve(decl->getName(), ResolutionType::Any, !anyOrder); | ||
if (prev->empty()) continue; | ||
|
||
for (auto p : *prev) { | ||
const IR::Node* pnode = p->getNode(); | ||
if (pnode == node) continue; | ||
if (pnode->is<IR::Type_Method>() && node->is<IR::Type_Method>()) { | ||
auto md = node->to<IR::Type_Method>(); | ||
auto mp = pnode->to<IR::Type_Method>(); | ||
if (md->parameters->size() != mp->parameters->size()) | ||
continue; | ||
} | ||
if (pnode->is<IR::Type_Method>() && node->is<IR::Type_Method>()) | ||
// Methods can overload each other if they have a different number of arguments | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mbudiu-vmw You deleted the check that they have different numbers of parameters. Does this code now allow any pair of methods with the same name to shadow each other? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It will just avoid giving a shadowing warnings for all methods. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. Do you happen to know where that is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One case is in Type_Extern::lookupMethod. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool. Thanks. |
||
continue; | ||
|
||
::warning("%1% shadows %2%", decl->getName(), p->getName()); | ||
} | ||
} | ||
|
@@ -287,36 +284,34 @@ bool ResolveReferences::preorder(const IR::Type_Name* type) { | |
|
||
bool ResolveReferences::preorder(const IR::P4Control *c) { | ||
refMap->usedName(c->name.name); | ||
addToContext(c); | ||
addToContext(c->type->typeParameters); | ||
addToContext(c->type->applyParams); | ||
addToContext(c->constructorParams); | ||
addToContext(c); // add the locals | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jnfoster: This change ensures that parameters enter the scope before the locals. |
||
return true; | ||
} | ||
|
||
void ResolveReferences::postorder(const IR::P4Control *c) { | ||
removeFromContext(c); | ||
removeFromContext(c->constructorParams); | ||
removeFromContext(c->type->applyParams); | ||
removeFromContext(c->type->typeParameters); | ||
removeFromContext(c); | ||
checkShadowing(c); | ||
} | ||
|
||
bool ResolveReferences::preorder(const IR::P4Parser *c) { | ||
refMap->usedName(c->name.name); | ||
addToContext(c); | ||
addToContext(c->type->typeParameters); | ||
addToContext(c->type->applyParams); | ||
addToContext(c->constructorParams); | ||
bool ResolveReferences::preorder(const IR::P4Parser *p) { | ||
refMap->usedName(p->name.name); | ||
addToContext(p->type->typeParameters); | ||
addToContext(p->type->applyParams); | ||
addToContext(p->constructorParams); | ||
addToContext(p); | ||
return true; | ||
} | ||
|
||
void ResolveReferences::postorder(const IR::P4Parser *c) { | ||
removeFromContext(c->constructorParams); | ||
removeFromContext(c->type->applyParams); | ||
removeFromContext(c->type->typeParameters); | ||
removeFromContext(c); | ||
checkShadowing(c); | ||
void ResolveReferences::postorder(const IR::P4Parser *p) { | ||
removeFromContext(p); | ||
removeFromContext(p->constructorParams); | ||
removeFromContext(p->type->applyParams); | ||
removeFromContext(p->type->typeParameters); | ||
} | ||
|
||
bool ResolveReferences::preorder(const IR::Function* function) { | ||
|
@@ -350,15 +345,14 @@ void ResolveReferences::postorder(const IR::TableProperties *p) { | |
|
||
bool ResolveReferences::preorder(const IR::P4Action *c) { | ||
refMap->usedName(c->name.name); | ||
addToContext(c); | ||
addToContext(c->parameters); | ||
addToContext(c); | ||
return true; | ||
} | ||
|
||
void ResolveReferences::postorder(const IR::P4Action *c) { | ||
removeFromContext(c->parameters); | ||
removeFromContext(c); | ||
checkShadowing(c); | ||
removeFromContext(c->parameters); | ||
} | ||
|
||
bool ResolveReferences::preorder(const IR::Type_Method *t) { | ||
|
@@ -397,7 +391,6 @@ bool ResolveReferences::preorder(const IR::ParserState *s) { | |
void ResolveReferences::postorder(const IR::ParserState *s) { | ||
removeFromContext(s); | ||
resolveForward.pop_back(); | ||
checkShadowing(s); | ||
} | ||
|
||
bool ResolveReferences::preorder(const IR::Declaration_MatchKind *d) | ||
|
@@ -425,7 +418,7 @@ bool ResolveReferences::preorder(const IR::BlockStatement *b) | |
{ addToContext(b); return true; } | ||
|
||
void ResolveReferences::postorder(const IR::BlockStatement *b) | ||
{ removeFromContext(b); checkShadowing(b); } | ||
{ removeFromContext(b); } | ||
|
||
bool ResolveReferences::preorder(const IR::Declaration_Instance *decl) { | ||
refMap->usedName(decl->name.name); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
Copyright 2017 VMware, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
control c(bit<32> p)(bool p) { | ||
apply {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
Copyright 2017 VMware, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
control MyIngress<p>(inout bit<32> p) { | ||
apply {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
Copyright 2017 VMware, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
control MyIngress<p>(inout bit<32> x)(bit<32> p) { | ||
apply {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
Copyright 2017 VMware, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
control MyIngress<p>(inout bit<32> p)(bit<32> p) { | ||
apply {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
control c(bit<32> p)(bool p) { | ||
apply { | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
../testdata/p4_16_errors/dup-param.p4(17): error: Duplicated parameter name: p and p | ||
control c(bit<32> p)(bool p) { | ||
^ | ||
../testdata/p4_16_errors/dup-param.p4(17) | ||
control c(bit<32> p)(bool p) { | ||
^ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
control MyIngress<p>(inout bit<32> p) { | ||
apply { | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
../testdata/p4_16_errors/dup-param1.p4(17): error: Duplicated parameter name: p and p | ||
control MyIngress<p>(inout bit<32> p) { | ||
^ | ||
../testdata/p4_16_errors/dup-param1.p4(17) | ||
control MyIngress<p>(inout bit<32> p) { | ||
^ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
control MyIngress<p>(inout bit<32> x)(bit<32> p) { | ||
apply { | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
../testdata/p4_16_errors/dup-param2.p4(17): error: Duplicated parameter name: p and p | ||
control MyIngress<p>(inout bit<32> x)(bit<32> p) { | ||
^ | ||
../testdata/p4_16_errors/dup-param2.p4(17) | ||
control MyIngress<p>(inout bit<32> x)(bit<32> p) { | ||
^ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
control MyIngress<p>(inout bit<32> p)(bit<32> p) { | ||
apply { | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
../testdata/p4_16_errors/dup-param3.p4(17): error: Duplicated parameter name: p and p | ||
control MyIngress<p>(inout bit<32> p)(bit<32> p) { | ||
^ | ||
../testdata/p4_16_errors/dup-param3.p4(17) | ||
control MyIngress<p>(inout bit<32> p)(bit<32> p) { | ||
^ | ||
../testdata/p4_16_errors/dup-param3.p4(17): error: Duplicated parameter name: p and p | ||
control MyIngress<p>(inout bit<32> p)(bit<32> p) { | ||
^ | ||
../testdata/p4_16_errors/dup-param3.p4(17) | ||
control MyIngress<p>(inout bit<32> p)(bit<32> p) { | ||
^ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
Copyright 2017 VMware, Inc. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
header H {} | ||
|
||
control MyIngress(inout H p) { | ||
bit<8> p = 0; | ||
apply { | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
header H { | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
header H { | ||
} | ||
|
||
control MyIngress(inout H p) { | ||
bit<8> p = 0; | ||
apply { | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
../testdata/p4_16_samples/shadow3.p4(20): warning: p shadows p | ||
bit<8> p = 0; | ||
^ | ||
../testdata/p4_16_samples/shadow3.p4(19) | ||
control MyIngress(inout H p) { | ||
^ | ||
warning: Program does not contain a `main' module |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,6 @@ | ||
#include <core.p4> | ||
|
||
control c(out bool x) { | ||
bit<32> x; | ||
table t1() { | ||
key = { | ||
x: exact; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this will now check every case of shadowing. Are there cases where shadowing should not be a warning? Actions in a control with the same name as some non-action global thing? Cases where a programmer might reasonably expect to reuse a name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All I can tell you is that there are no new warnings on the public tests we have.
If this is too strict we can refine it later.