Why `ARGV` got `aa;"bb"` when I call `func("aa";"bb")`?

Why the following code outputs aa;”bb”, instead of aa;bb or “aa”;”bb”?

function(func)
    message("${ARGV}")
endfunction()

func("aa";"bb")

It’s for legacy reasons. Refer the CMake grammar symbol unquoted_argument and the note below it for details. In short, quotes should not be written this way in new CMake code.

What is the logic that makes it aa;"bb" (not expanded as a list, at that!) and not e.g. aa";"bb though? The unquoted_legacy production isn’t actually in the docs except as fairly vague prose, so it’s kind of difficult to tell what actually qualifies and how it gets interpreted. (I get that the idea is that I wouldn’t need to when doing things properly, but I do mess up on, uh, occasion, so it’d be nice to know what to expect.)

It can’t be that any argument that has quotes anywhere that’s not the start or the end (is always treated as a single argument and) has the first matching pair of quotes stripped: I tried a="${B}" by mistake at one point and got a="" for my troubles, so all the quotes that were in the original got passed through.