Yesterday I was a bit distracted by loop pragma parsing (D64471), but still am a bit today too (this patch).
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
| clang/lib/Parse/ParsePragma.cpp | ||
|---|---|---|
| 1015 ↗ | (On Diff #209194) | I guess this does behave slightly different, i.e. the assert in a release build. Before, in a release build, "unroll" was returned for an unexpected pragma, but now we return the empty string "". |
| clang/lib/Parse/ParsePragma.cpp | ||
|---|---|---|
| 1009 ↗ | (On Diff #209194) | getName() returns StringRef. No need to use a std::string yet. |
| 1011–1014 ↗ | (On Diff #209194) | This unconditionally creates (at least) 5 std::string objects. |
| 1040 ↗ | (On Diff #209194) | [style] We don't use const for local variables. Could also use auto here since the type is already explicit on the RHS. [suggestion] IsLoopHint would indicate the meaning of the boolean variable. |
| lib/Parse/ParsePragma.cpp | ||
|---|---|---|
| 1011 ↗ | (On Diff #209299) | [serious] I know I already accepted the patch, but I just noticed something: |
| lib/Parse/ParsePragma.cpp | ||
|---|---|---|
| 1011 ↗ | (On Diff #209299) | Oopsy, thanks for spotting this! Will fix this! |
| clang/lib/Parse/ParsePragma.cpp | ||
|---|---|---|
| 1010 ↗ | (On Diff #212878) | [serious] Use-after-free here again. This line will do the following: StringRef ClangLoopStr;
{
std::string tmp = "clang loop " + Str.str()
ClangLoopStr = tmp;
// tmp.~string()
}
// Any use of ClangLoopStr will use memory released by tmp.~string()Let me suggest a solution: std::string ClangLoopStr = (Twine("clang loop ") + Str).str();
std::string Result = llvm::StringSwitch<StringRef>(Str)
.Case("loop", ClangLoopStr)
.Case("unroll_and_jam", Str)
.Case("unroll", Str)
.Default("");
return Result; // NRVO, ClangLoopStr will be released here, but if it was chosen by the StringSwitch, Result will hold a copy, so ClangLoopStr is not referenced anymore.Note that this will alloc one more std::string in the non-ClangLoopStr cases than before the patch, but I don't think it's important. |
Sorry, should have done my std::string, StringRef, and Twine homework a lot better!
Thanks for your help and suggestions, will fix this.
| clang/lib/Parse/ParsePragma.cpp | ||
|---|---|---|
| 1010 ↗ | (On Diff #215162) | [nit] I am surprised it works without llvm:: qualifier for llvm::Twine. Maybe add it for consistency? |
| 1016 ↗ | (On Diff #215162) | [nit] One could just return llvm::StringSwitch... without a Result variable. I used it in the suggestion so I could comment on what happens when returning. Personally, there is nothing that I could care less about, so use what you prefer. |