[PATCH] ms-inline-asm: Scope inline asm labels to functions
Reid Kleckner
rnk at google.com
Thu Jul 31 12:50:38 PDT 2014
On Thu, Jul 24, 2014 at 4:26 PM, Ehsan Akhgari <ehsan.akhgari at gmail.com>
wrote:
> On Thu, Jul 24, 2014 at 2:52 PM, Reid Kleckner <rnk at google.com> wrote:
>
>> ================
>> Comment at: lib/Parse/ParseStmtAsm.cpp:96
>> @@ -95,1 +95,3 @@
>>
>> + void LookupInlineAsmLabel(StringRef &Identifier, llvm::SourceMgr &LSM,
>> + llvm::SMLoc Location, bool Create) {
>> ----------------
>> You can return a StringRef directly.
>>
>> ================
>> Comment at: lib/Sema/SemaDecl.cpp:1492
>> @@ -1491,1 +1491,3 @@
>>
>> + HandleMSAsmLabelsOnScopePop();
>> +
>> ----------------
>> I believe ActOnPopScope happens on any closing curly brace, so this won't
>> do the "right" thing:
>> void f() {
>> bool failed;
>> __asm retry:
>> {
>> failed = g();
>> } // The label is cleared here.
>> if (failed)
>> __asm jmp retry
>> }
>>
>> Thinking more carefully, I don't think having the label map right on Sema
>> works at all in the general case of nested functions. Consider this C++
>> example with inner classes:
>> void f() {
>> __asm some_label:
>> struct A {
>> static void g() {
>> __asm jmp some_label ; This should jump forwards
>> __asm some_label:
>> __asm nop
>> }
>> };
>> }
>>
>> You can build similar test cases from C++11 lambdas and Obj-C blocks, and
>> now OpenMP captured statements.
>>
>> We need to associate this label map with the function we're currently
>> processing. Now that I'm considering the actual implementation
>> difficulties, I'm going back to your "proposal #3" on PR20023, where we
>> model these labels as regular label statements. That way, we reuse all the
>> right name lookup machinery. We won't be able to 'goto' a label from an
>> inline asm statement or 'jmp' to a non-asm label, so if you go this way,
>> please diagnose both cases. You can probably add a bit to LabelDecl to
>> track whether the label was from MS inline asm or regular source code.
>>
>> Apologies for the runaround, but I think it's probably better to rewrite
>> along these lines. What do you think?
>>
>
> Hmm, there are a number of problems with that approach. One is that we
> need to break up __asm blocks and perhaps remember part of the parser state
> until we hit the end of the function (such as the number of braces we have
> seen, their source locations, etc.) which complicates the parsing code, and
> actually needs us to do something at the end of the function too. It also
> means that we won't be able to reuse LookupInlineAsmIdentifier, since
> AFAICT labels are not Expr's. Also, it will mean that the __asm blocks
> will be disjoint across labels, even after my __asm block joining patch.
>
I'm don't want to support going to labels in asm or jumping out: we
shouldn't break up __asm blobs and introduce new LabelStmts. Instead, we
should synthesize a LabelDecl with no associated LabelStmt and use the rest
of the usual label machinery to insert it into the correct function scope.
However, when we see 'goto label_from_asm', we'll have to add code to
reject that. Presumably we can tell the two kinds of LabelDecl apart by
the presence or absence of a LabelStmt.
> It seems like your main objection to this approach is to storing the label
> map on Sema, and that is quite fair (and I should add tests for that!).
> But isn't a much easier solution to that to store the label map at the
> right place? I've been looking at the code that handles LabelDecl's, and I
> think we can get by with storing the map on Scope objects, and do something
> similar to Sema::LookupOrCreateLabel to make sure we are accessing the
> right function scope. I think with that change, everything else in my
> patch will work properly.
>
That would work too, but I think you'll end up duplicating lots of the
label processing logic if you go that way.
It's probably also worth thinking about how to handle these kinds of test
cases:
void foo() {
__asm jmp bar ; is 'bar' a function name or label?
}
void bar();
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140731/626c9173/attachment.html>
More information about the cfe-commits
mailing list