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
Fix issues 19655, 19656, 19657, 19746 & 19750 #9471
Conversation
The Semantic (pass 1) analysis for classes is handled by visit(ClassDeclaration ) method of DsymbolSemanticVisitor class. For a given class, this method may be run multiple times in order to resolve forward references. The method incrementally tries to resolve the types referred to by the members of the class. The subsequent calls to this method are short-circuited if the class members have been fully analyzed. For this the code tests that it is not the first/main call to the method (semanticRun == PASS.init else branch), scx is not set, and that the cldec.symtab is already set. If all these conditions are met, the method returns. But before returning, the method was setting cldec.semanticRun to PASS.semanticdone. It should not set semanticRun since the class has not been fully analyzed yet. The base class analysis for this class could be pending and as a result vtable may not have been fully created. This fake setting of semanticRun results in the semantic analyzer to believe that the class has been fully analyzed. As exposed by the issues 19656, 19657, 19746 and 19750, it may result in compile time errors when a derived type class is getting analyzed and because of this fake semanticdone on the base class, the semantic analysis construes that an overridden method is not defined in the base class. Issue 19655 exposes a scenario where a buggy vtable may be created and a call to class method may result in execution of some adhoc code.
Thanks for your pull request and interest in making D better, @puneet! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "stable + dmd#9471" |
The tests fail because it is not able to create test_results/runnable/test19655.sh.out. The same happened with my local run. But a subsequent run was successful. Am I missing something? |
I think generally we have either shell script tests or source tests but not both. If the related files need to be compiled all together the they should go in |
@puneet can you consolidate your tests please? |
I need multiple files because the import sequence is important to recreate the test scenario. |
Alright, I get what you are saying. I now have created shell script wrappers that write out D files and then compiles. I will update the PR. But I am still getting this error when I run the tests locally. But if I run make again, the error goes. As I understand the compile is happening too quickly and the makefile misses the output file. I can not make out why it happens for my sh files and not for the other sh tests that already exist. Any clues? Test compilable/test19656.sh failed. The logged output: |
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.
The tests are a bit hacky, but then so it the whole test suite. Lets get this merged.
That doesn't even cut it. Let's please please please only use shell tests when absolutely necessary as they slow down the testsuite, are harder to debug and port to other runtimes. Also, creating files in the shell scripts is an absolute anti-pattern. @puneet thanks a lot for your PR, but could you please convert these test to proper test files?
|
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.
Just a few comments regarding the tests. Can you please give someone who's experienced with the testsuite a reasonable timeframe for reviewing?
void func (Thud ) { } | ||
void thunk () { } | ||
} | ||
EOF |
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.
This should have been in extra-files instead of creating on-the-fly.
@@ -0,0 +1,57 @@ | |||
#! /usr/bin/env bash | |||
|
|||
TEST_DIR=${OUTPUT_BASE} |
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.
TEST_DIR is an existing exported variable.
dmd/test/tools/exported_vars.sh
Line 3 in 4edae68
export TEST_DIR=$1 # TEST_DIR should be one of compilable, fail_compilation or runnable |
While possible, probably not a good idea to overwrite it.
${TEST_DIR}${SEP}test19657e.d ${TEST_DIR}${SEP}test19657f.d \ | ||
${TEST_DIR}${SEP}test19657g.d | ||
|
||
rm -f ${TEST_DIR}${SEP}${TEST_NAME}${OBJ} ${TEST_DIR}${SEP}${TEST_NAME}*.d |
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.
Wasn't the entire point of creating a directory that you can remove it in one command?
|
||
TEST_DIR=${OUTPUT_BASE} | ||
|
||
mkdir -p ${TEST_DIR} |
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.
Note that
- (1) the files should have been not generated on the fly and placed e.g. in
EXTRA_FILES
- (2)
${OUTPUT_BASE}a
would have worked too
dmd/test/tools/exported_vars.sh
Line 7 in 4edae68
export OUTPUT_BASE=${RESULTS_TEST_DIR}/${TEST_NAME} # reference to the resulting files without a suffix, e.g. test_results/runnable/test123 |
|
||
cat >${TEST_DIR}${SEP}test19657d.d <<EOF | ||
import test19657a; | ||
class Trump: Foo {} |
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.
Let's not be political here.
@@ -0,0 +1,51 @@ | |||
#! /usr/bin/env bash |
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.
This is an ill-formed pseudo she-bang header. It only works because the scripts aren't executed, but sourced.
I recommend removing it.
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.
Hello @wilzbach, thanks for your feedback.
I am willing to implement your suggestions, but I see that the PR is already merged. Should I still go ahead push the modifications?
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.
Yes, it was merged too eagerly. Please do so by opening a new PR. Thanks!
Ping. @thewilsonator - this is yet another example why waiting for more than a day is very important. Follow-ups to a PR happen rarely and thus the debt just aggregates ... |
Rework as non-shell test: #10908 |
Fix issues 19655, 19656, 19657, 19746 & 19750 merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
[dmd-cxx] Fix issues 19655, 19656, 19657, 19746 & 19750 (#9471)
The Semantic (pass 1) analysis for classes is handled by visit(ClassDeclaration ) method of DsymbolSemanticVisitor class. For a given class, this method may be run multiple times in order to resolve forward references. The method incrementally tries to resolve the types referred to by the members of the class.
The subsequent calls to this method are short-circuited if the class members have been fully analyzed. For this the code tests that it is not the first/main call to the method (semanticRun == PASS.init else branch), scx is not set, and that the cldec.symtab is already set. If all these conditions are met, the method returns. But before returning, the method was setting cldec.semanticRun to PASS.semanticdone. It should not set semanticRun since the class has not been fully analyzed yet. The base class analysis for this class could be pending and as a result vtable may not have been fully created.
This fake setting of semanticRun results in the semantic analyzer to believe that the class has been fully analyzed. As exposed by the issues 19656, 19657, 19746 and 19750, it may result in compile time errors when a derived type class is getting analyzed and because of this fake semanticdone on the base class, the semantic analysis construes that an overridden method is not defined in the base class. Issue 19655 exposes a scenario where a buggy vtable may be created and a call to class method may result in execution of some adhoc code.