expecta icon indicating copy to clipboard operation
expecta copied to clipboard

Matchers do not warn on improper use

Open adamkaplan opened this issue 9 years ago • 10 comments

Clang seems quite confused by the chained properties DSL. Today I found that some of my matchers were missing trailing parens, effectively returning but not executing the matcher. The specific case was .beNil vs .beNil(). The former compiles without any warning and appears to "pass", while in fact doing nothing at all.

This shouldn't happen. It might be a Clang bug since Clang changes it's mind based on the precedence. screenshot 2015-08-07 17 36 48

I tried enabling some additional Clang flags to no avail. Ideally Expecta shouldn't go quietly into the night with all of your tests running as no-ops...

adamkaplan avatar Aug 07 '15 21:08 adamkaplan

I did search first, but then... #149

adamkaplan avatar Aug 07 '15 21:08 adamkaplan

Yeah, so far we've not been able to figure out a way to enforce the () either.

orta avatar Aug 07 '15 21:08 orta

Worth filing something against Clang? It might be an edge case in the AST.

adamkaplan avatar Aug 07 '15 21:08 adamkaplan

Probably, it's basically accessing the block but doing nothing - something that should raise a warning if it's not inside an if statement.

orta avatar Aug 08 '15 00:08 orta

This is a real head scratcher! I distilled the problem down to a very simple example for the future humans who will know how to fix this:

https://gist.github.com/adamkaplan/3c69fda47bf02790a860#file-expexpectawarningdemo-m

adamkaplan avatar Aug 09 '15 00:08 adamkaplan

This is really interesting. I think this does indeed demonstrate a limitation in Clang. I think it's being tripped up by the expect macro. The following, which uses the _EXP_expect() function instead of a macro, correctly emits a warning when compiled with Clang:

// Emits warning: "Property access result unused - getters should not be used for side effects"
_EXP_expect(nil, 0, "", ^id{ return nil; }).to.beNil;

modocache avatar Aug 15 '15 02:08 modocache

Yup, definitely related to the macro expansion. I filed a a bug against Clang last week but forgot to link it:

https://llvm.org/bugs/show_bug.cgi?id=24404

adamkaplan avatar Aug 15 '15 02:08 adamkaplan

Oh, awesome! Thanks for filing the bug! :+1:

modocache avatar Aug 15 '15 02:08 modocache

Hi there, seems it's done intentionally. See the comment: https://github.com/llvm-mirror/clang/blob/master/lib/Sema/SemaStmt.cpp#L199

Though it works as expected when the ShouldSuppress omitted.

AlexDenisov avatar Aug 15 '15 11:08 AlexDenisov

@AlexDenisov The intention per the comments is a few degrees off from observed behavior.

The unused result does not originate within macro body expansion, but rather a function called on the result of the expansion. In this case the function -beNil produces the unused result, not the macro. The way this looks, any code that directly operates on a macro loses some useful diagnostics...

adamkaplan avatar Aug 17 '15 15:08 adamkaplan