@@ -5094,9 +5094,14 @@ prop_checkOverwrittenExitCode2 = verifyNot checkOverwrittenExitCode "x; [ $? -eq
50945094prop_checkOverwrittenExitCode3 = verify checkOverwrittenExitCode " x; echo \" Exit is $?\" ; [ $? -eq 0 ]"
50955095prop_checkOverwrittenExitCode4 = verifyNot checkOverwrittenExitCode " x; [ $? -eq 0 ] && echo Success"
50965096prop_checkOverwrittenExitCode5 = verify checkOverwrittenExitCode " x; if [ $? -eq 0 ]; then var=$?; fi"
5097+ prop_checkOverwrittenExitCode5a = verify checkOverwrittenExitCode " x; if [ $? -eq 0 ]; then exit $?; fi"
50975098prop_checkOverwrittenExitCode6 = verify checkOverwrittenExitCode " x; [ $? -gt 0 ] && fail=$?"
5099+ prop_checkOverwrittenExitCode6a = verify checkOverwrittenExitCode " x; [ $? -eq 0 ] && exit $?"
50985100prop_checkOverwrittenExitCode7 = verifyNot checkOverwrittenExitCode " [ 1 -eq 2 ]; status=$?"
50995101prop_checkOverwrittenExitCode8 = verifyNot checkOverwrittenExitCode " [ 1 -eq 2 ]; exit $?"
5102+ prop_checkOverwrittenExitCode9 = verifyNot checkOverwrittenExitCode " [[ -e \" ./lockfile\" ]] || retval=$?"
5103+ prop_checkOverwrittenExitCode10 = verifyNot checkOverwrittenExitCode " [ -e \" ./lockfile\" ] || retval=$?"
5104+ prop_checkOverwrittenExitCode11 = verifyNot checkOverwrittenExitCode " [ 1 -eq 2 ] && status=$?"
51005105checkOverwrittenExitCode params t =
51015106 case t of
51025107 T_DollarBraced id _ val | getLiteralString val == Just " ?" -> check id
@@ -5110,10 +5115,16 @@ checkOverwrittenExitCode params t =
51105115
51115116 let idToToken = idMap params
51125117 exitCodeTokens <- traverse (\ k -> Map. lookup k idToToken) $ S. toList exitCodeIds
5118+ let inAssignment = isInAssignment id
5119+ condHasDollarQ = conditionContainsDollarQuestion id exitCodeIds
5120+ suppress = inAssignment && not condHasDollarQ
51135121 return $ do
5114- when (all isCondition exitCodeTokens && not (usedUnconditionally cfga t exitCodeIds)) $
5122+ when (all isCondition exitCodeTokens
5123+ && not (usedUnconditionally cfga t exitCodeIds)
5124+ && not suppress) $
51155125 warn id 2319 " This $? refers to a condition, not a command. Assign to a variable to avoid it being overwritten."
5116- when (all isPrinting exitCodeTokens) $
5126+ when (all isPrinting exitCodeTokens
5127+ && not suppress) $
51175128 warn id 2320 " This $? refers to echo/printf, not a previous command. Assign to variable to avoid it being overwritten."
51185129
51195130 isCondition t =
@@ -5133,6 +5144,26 @@ checkOverwrittenExitCode params t =
51335144 Just " printf" -> True
51345145 _ -> False
51355146
5147+ isInAssignment tokenId =
5148+ let token = Map. lookup tokenId (idMap params)
5149+ in maybe False (\ tok -> any isAssignmentToken $ getPath (parentMap params) tok) token
5150+ where
5151+ isAssignmentToken (T_Assignment _ _ _ _ _) = True
5152+ isAssignmentToken _ = False
5153+
5154+ conditionContainsDollarQuestion tokenId exitIds =
5155+ let tree = parentMap params
5156+ tokenMap = idMap params
5157+ condTokens = mapMaybe (`Map.lookup` tokenMap) (S. toList exitIds)
5158+ dollarQTokens = [(tid, tok) | (tid, tok) <- Map. toList tokenMap,
5159+ tid /= tokenId,
5160+ isDollarQ tok]
5161+ isDollarQ (T_DollarBraced _ _ val) = getLiteralString val == Just " ?"
5162+ isDollarQ _ = False
5163+ in any (\ (_, dqToken) ->
5164+ any (\ cond -> isParentOf tree cond dqToken) condTokens
5165+ ) dollarQTokens
5166+
51365167
51375168prop_checkUnnecessaryArithmeticExpansionIndex1 = verify checkUnnecessaryArithmeticExpansionIndex " a[$((1+1))]=n"
51385169prop_checkUnnecessaryArithmeticExpansionIndex2 = verifyNot checkUnnecessaryArithmeticExpansionIndex " a[1+1]=n"
0 commit comments