The failing test case:

src/test/java/org/joda/time/TestDateTimeZone.java:303-334
    public void testForOffsetHoursMinutes_int_int() {
        assertEquals(DateTimeZone.UTC, DateTimeZone.forOffsetHoursMinutes(0, 0));
        assertEquals(DateTimeZone.forID("+23:59"), DateTimeZone.forOffsetHoursMinutes(23, 59));
        assertEquals(DateTimeZone.forID("+03:15"), DateTimeZone.forOffsetHoursMinutes(3, 15));
        assertEquals(DateTimeZone.forID("-02:00"), DateTimeZone.forOffsetHoursMinutes(-2, 0));
        assertEquals(DateTimeZone.forID("-02:30"), DateTimeZone.forOffsetHoursMinutes(-2, 30));
        assertEquals(DateTimeZone.forID("-23:59"), DateTimeZone.forOffsetHoursMinutes(-23, 59));
        try {
            DateTimeZone.forOffsetHoursMinutes(2, 60);
            fail();
        } catch (IllegalArgumentException ex) {}
        try {
            DateTimeZone.forOffsetHoursMinutes(-2, 60);
            fail();
        } catch (IllegalArgumentException ex) {}
        try {
            DateTimeZone.forOffsetHoursMinutes(2, -1);
            fail();
        } catch (IllegalArgumentException ex) {}
        try {
            DateTimeZone.forOffsetHoursMinutes(-2, -1);
            fail();
        } catch (IllegalArgumentException ex) {}
        try {
            DateTimeZone.forOffsetHoursMinutes(24, 0);          // <-- wrong behaviour
            fail();                                             // <-- TC fails here
        } catch (IllegalArgumentException ex) {}
        try {
            DateTimeZone.forOffsetHoursMinutes(-24, 0);
            fail();
        } catch (IllegalArgumentException ex) {}
    }  

The faulty code:

Line is covered but NOT in slice
Line is covered and in slice
Line is in slice but NOT covered
src/main/java/org/joda/time/DateTimeZone.java:254-274
public static DateTimeZone forOffsetHoursMinutes(int hoursOffset, int minutesOffset) throws IllegalArgumentException {
    if (hoursOffset == 0 && minutesOffset == 0) {
        return DateTimeZone.UTC;
        }
    if (minutesOffset < 0 || minutesOffset > 59) {
        throw new IllegalArgumentException("Minutes out of range: " + minutesOffset);
    }
    int offset = 0;
    try {
        int hoursInMinutes = FieldUtils.safeMultiply(hoursOffset, 60);            //<-- BUG!!
        if (hoursInMinutes < 0) { 
            minutesOffset = FieldUtils.safeAdd(hoursInMinutes, -minutesOffset);   //<-- BUG!!
        } else {
            minutesOffset = FieldUtils.safeAdd(hoursInMinutes, minutesOffset);    //<-- BUG!!
        }
        offset = FieldUtils.safeMultiply(minutesOffset, DateTimeConstants.MILLIS_PER_MINUTE);
    } catch (ArithmeticException ex) {
        throw new IllegalArgumentException("Offset is too large");
    }
    return forOffsetMillis(offset);
}

Other code:

src/main/java/org/joda/time/DateTimeZone.java:602-620
private static int parseOffset(String str) {
    // Can't use a real chronology if called during class
    // initialization. Offset parser doesn't need it anyhow.
    Chronology chrono = new BaseChronology() { 
        public DateTimeZone getZone() {
            return null;
        }
        public Chronology withUTC() {
            return this;
        }
        public Chronology withZone(DateTimeZone zone) {
            return this;
        }
        public String toString() {
            return getClass().getName();
        }
    };
    return -(int) offsetFormatter().withChronology(chrono).parseMillis(str); 
}