wanted: FORMAT should warn on (FORMAT "FOO ~A" ...)

Bug #327223 reported by Tobias C. Rittweiler
4
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Wishlist
Unassigned
Declined for Trunk by Nikodemus Siivola

Bug Description

I regularly forget to add T, and simply write (FORMAT "FOO ~A" ...).

Notice that a string is valid as first argument to FORMAT, that's the
reason why this isn't complained about by type inference.

Still a string literal may not be modified, so SBCL has all right to
signal a full warning in this case.

description: updated
Changed in sbcl:
importance: Undecided → Wishlist
status: New → Confirmed
Revision history for this message
Roman Marynchak (roman-marynchak) wrote :

CLHS says that a string should have a fill pointer in order to be an acceptable first argument to FORMAT. So, in such a case SBCL should give a compilation error, not a warning. When a string has no fill pointer, the code will fail to execute anyway, due to SB-IMPL::MAKE-FILL-POINTER-OUTPUT-STREAM call failure.

So it seems to me that the right way is to modify the FORMAT function info in file /src/compiler/fndb.lisp to be like this:

(defknown format ((or (member nil t) stream
                        (and string (satisfies array-has-fill-pointer-p)))
                  (or string function) &rest t)
  (or string null)
  (explicit-check))

Here a string as a first argument should also pass array-has-fill-pointer-p predicate. Unfortunately, such a modification breaks the cross-compilation and SBCL goes to LDB. Is SATISFIES prohibited to use with DEFKNOWN, or I have used it in a wrong way? The LDB info is:

     0: Foreign fp = 0x7ffff517c080, ra = 0x410fbf
   1: Foreign fp = 0x7ffff517c0b0, ra = 0x41471d
   2: Foreign fp = 0x7ffff517c0f0, ra = 0x41215a
   3: Foreign fp = 0x7ffff517c5a0, ra = 0x7ffff79cd080
   4: (SB!C::TL-XEP COMMON-LISP::ERROR)
   5: COMMON-LISP::FDEFINITION
   6: SB!C::CONSTANT-FUNCTION-CALL-VALUE
   7: SB!C::CONSTANT-FUNCTION-CALL-VALUE
   8: SB!C::CONSTANT-FUNCTION-CALL-P
   9: SB!KERNEL::CTYPEP

Regards,
Roman

Revision history for this message
Roman Marynchak (roman-marynchak) wrote :

The attached patch provides the required functionality and detects a string without a fill pointer as a first FORMAT argument. The only thing I don't like in that code is the kind of the error. As for now it is a fatal error, because COMPILER-ERROR does not work in the optimizer body. Maybe I should bind *compiler-error-context* to make it work?

This is my first patch to SBCL, and in case I do something wrong, please let me know and I will try to improve it.

Regards,
Roman

Revision history for this message
Christophe Rhodes (csr21-cantab) wrote : Re: [Bug 327223] Re: wanted: FORMAT should warn on (FORMAT "FOO ~A" ...)

Roman Marynchak <email address hidden> writes:

> The attached patch provides the required functionality and detects a
> string without a fill pointer as a first FORMAT argument. The only thing
> I don't like in that code is the kind of the error. As for now it is a
> fatal error, because COMPILER-ERROR does not work in the optimizer body.
> Maybe I should bind *compiler-error-context* to make it work?

I would suggest modelling the diagnostic on the other format argument
checking (in the case of a constant control string): that is, to emit
warnings, not errors of any kind. A warning that is not a style-warning
is enough to treat a compilation as unsuccessful, while it can be
muffled by users who know what they are doing.

> This is my first patch to SBCL, and in case I do something wrong, please
> let me know and I will try to improve it.

At least here, the patch either has poor indentation or has tabs for
whitespace, neither of which is ideal :-)

Christophe

Revision history for this message
Roman Marynchak (roman-marynchak) wrote :

Christophe, thank you for the valuable feedback :) Both notes are counted in the new variant of the patch. Also, I moved the fix to FORMAT transform to avoid multiple warnings generation in the iterative optimizer calls. So, now SBCL warns about the wrong FORMAT argument:

* (defun f() (format "FOO~A" "bar"))
; in: LAMBDA NIL
; (FORMAT "FOO~A" "bar")
;
; caught WARNING:
; A simple string "FOO~A" is not a valid first argument to FORMAT.
;
; compilation unit finished
; caught 1 WARNING condition

F
*

Regards,
Roman

Changed in sbcl:
assignee: nobody → Roman Marynchak (roman-marynchak)
tags: added: review
tags: removed: review
Changed in sbcl:
assignee: Roman Marynchak (roman-marynchak) → nobody
Changed in sbcl:
assignee: nobody → Nikodemus Siivola (nikodemus)
status: Confirmed → In Progress
tags: added: pending
Revision history for this message
Nikodemus Siivola (nikodemus) wrote :

In 1.0.46.8.

Changed in sbcl:
assignee: Nikodemus Siivola (nikodemus) → nobody
status: In Progress → Fix Committed
tags: removed: pending
Changed in sbcl:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.